NSString:将值分配给 属性 时发生泄漏
NSString : leak when assigning value to a property
假设我们不使用 ARC。
假设我们有一个非常简单的 class,我们在其中声明了 2 个 NSString 属性,如下所示:
@interface Foo : UIView {}
-(id)initWithArguments:(NSString*)mess title:(NSString*)tit;
@property(nonatomic, retain) NSString *message;
@property(nonatomic, retain) NSString *title;
@end
并在实施中:
@implementation Foo
@synthesize message, title;
-(id)initWithArguments:(NSString*)mess title:(NSString*)tit{
if((self = [super init])){
message = mess; // (1)
self.title = tit; // (2)
(...)
}
return self;
}
-(void)dealloc{
message = nil;
title = nil;
[super dealloc];
}
@end
现在,如果我从另一个 class 调用一个方法,我会在其中创建 2 个 NSString 和一个 Foo 实例,如下所示:
-(void)someMethod{
NSString *string1 = [NSString stringWithFormat:@"some text with %d things", 5];
NSString *string2 = [NSString stringWithFormat:@"other text with %d things", 5];
Foo *foo = [[Foo alloc] initWithArguments:string1 title:string2];
}
整个代码工作正常,不会崩溃,但是,如果我用仪器分析它,
- 调用(1)("message = mess;")
时不会造成泄漏
- 调用 (2)("self.title = tit;")
时导致泄漏
这很令人困惑,因为 stringWithFormat 是一个自动释放的对象,不是吗?
那么,自动释放的对象在分配给 属性 时如何导致泄漏???
我在某处读到,使用 "self.text = value;" 形式几乎总是比 "text = value;" 形式更好,因为第二个可能会导致泄漏。
实际上,在这段代码中恰恰相反。
并且...如果我使用像@"some text" 这样的常量 NSString 而不是 [NSString stringWithFormat] 返回的值,当然不会泄漏。
有什么想法吗?
在某些情况下您忘记调用(编译器生成的)setter 方法:
self.message = mess; // in init method
self.message = nil; // in dealloc method
self.title = nil; // ditto
在非 ARC 代码中使用 setter/getter 方法至关重要。
假设我们不使用 ARC。 假设我们有一个非常简单的 class,我们在其中声明了 2 个 NSString 属性,如下所示:
@interface Foo : UIView {}
-(id)initWithArguments:(NSString*)mess title:(NSString*)tit;
@property(nonatomic, retain) NSString *message;
@property(nonatomic, retain) NSString *title;
@end
并在实施中:
@implementation Foo
@synthesize message, title;
-(id)initWithArguments:(NSString*)mess title:(NSString*)tit{
if((self = [super init])){
message = mess; // (1)
self.title = tit; // (2)
(...)
}
return self;
}
-(void)dealloc{
message = nil;
title = nil;
[super dealloc];
}
@end
现在,如果我从另一个 class 调用一个方法,我会在其中创建 2 个 NSString 和一个 Foo 实例,如下所示:
-(void)someMethod{
NSString *string1 = [NSString stringWithFormat:@"some text with %d things", 5];
NSString *string2 = [NSString stringWithFormat:@"other text with %d things", 5];
Foo *foo = [[Foo alloc] initWithArguments:string1 title:string2];
}
整个代码工作正常,不会崩溃,但是,如果我用仪器分析它,
- 调用(1)("message = mess;") 时不会造成泄漏
- 调用 (2)("self.title = tit;") 时导致泄漏
这很令人困惑,因为 stringWithFormat 是一个自动释放的对象,不是吗? 那么,自动释放的对象在分配给 属性 时如何导致泄漏???
我在某处读到,使用 "self.text = value;" 形式几乎总是比 "text = value;" 形式更好,因为第二个可能会导致泄漏。
实际上,在这段代码中恰恰相反。
并且...如果我使用像@"some text" 这样的常量 NSString 而不是 [NSString stringWithFormat] 返回的值,当然不会泄漏。
有什么想法吗?
在某些情况下您忘记调用(编译器生成的)setter 方法:
self.message = mess; // in init method
self.message = nil; // in dealloc method
self.title = nil; // ditto
在非 ARC 代码中使用 setter/getter 方法至关重要。