如何将变量添加为属性会影响它?

时间:2012-02-28 05:41:50

标签: objective-c memory-management

在内存管理中将变量定义为属性有何不同?例如:

@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

似乎第一个是自动释放或类似的东西,而第二个是在整个课程的生命中保留。是这样,还是有什么区别?

2 个答案:

答案 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章中查阅更多相关信息。