在内存管理中将变量定义为属性有何不同?例如:
@interface foo {
NSString *theStr;
}
@end
@implementation foo
- (void)bar {
NSLog(theStr);
}
@end
对战:
@interface foo {
NSString *theStr;
}
@property(retain) NSString *theStr;
@end
@implementation foo
@synthesize theStr;
- (void)bar {
NSLog(theStr);
}
@end
似乎第一个是自动释放或类似的东西,而第二个是在整个课程的生命中保留。是这样,还是有什么区别?
答案 0 :(得分:1)
如果仅在界面中定义变量而不将其定义为属性(如第一个示例中所示),则意味着您必须自己处理与内存管理相关的所有事情。为该变量分配内容不会自动保留它,也不会将变量设置为其他内容释放先前的值。
将其定义为属性会在引擎盖下创建getter和setter方法。最重要的是,如果你将它与“retain”关键字一起使用,你的setter方法将保留新值(如果有的话,则释放旧值)。
请注意,只有使用点表示法(例如self.myStr = @"new string"
)或方法调用(例如[self setMyStr:@"new string"]
)时才会调用setter方法。如果您只是调用myStr = @"new string"
,则不会调用setter方法,您需要自己释放旧值并保留新值。
答案 1 :(得分:1)
我不认为第一个案例显示了一个自动释放的对象,它将取决于您如何管理该特定对象的创建和销毁。例如,当您创建该对象时,请调用:
//This string will indeed be autoreleased
theStr=[NSString stringWithString:@"Jibber jabber"];
//Or even
theStr=@"Jibber jabber";
但如果按以下方式创建内存管理,则必须负责内存管理:
//Manage my memory
theStr=[[NSString alloc] init];
//You have to release this property on the dealloc method
-(void)dealloc{
[theStr release];
[super dealloc];
}
在第二个示例中,您为属性theStr
创建了一个setter和getter方法,并通过添加nonatomic
属性,使您的属性不是线程安全,这意味着一个线程可以开始修改您的属性,而另一个已经在编辑它。通过将retain
属性设置为您的属性,将通过以下方式合成setter方法:
- (void) setTheStr:(NSString *) newString {
[newString retain];
[theStr release];
theStr = newSupervisor;
}
您可以在我最喜欢的一本书中Learning Objective-C 2.0在第12章中查阅更多相关信息。