我正在对NSURLConnection进行子类化,并使用MGTwitterEngine作为基础来帮助我入门。这可能与此无关。但是,我注意到在他们的代码中,他们不使用@property或@synthesize作为他们的ivars。他们用如下的访问器方法包装了ivars:
- (NSString *)identifier {
return [[_identifier retain] autorelease];
}我的问题有两部分。首先,retain和autorelease的作用是什么?在我看来,它会自行取消,或者更糟的是泄漏。
其次,如果我要将头文件更改为有:
@property (nonatomic, retain, readonly) NSString* _identifier;并且使用了@synthesize indentifier = _identifier,这样做不像访问器方法一样,而不必编写它吗?
也许这只是两种不同的方式来做同样的事情。但我想确保我有正确的理解。谢谢。
发布于 2010-10-24 17:18:02
使用@synthesize实际上只会创建一个setter和一个getter方法。为您自动生成的代码保证使用适当的内存管理,因此您不需要担心。
MGTwitterEngines使用return [[ivar retain] autorelease]实际上是正确的方法。让我们有两个例子。
假设getter定义为:
-(Foo)foo {
return foo;
}然后我们执行以下代码:
bar = [[bar alloc] init]; // bar的保留计数为1。foo = bar.foo; // foo har保留数为1(由bar拥有)。[bar release]; // Bar和所有它的象牙都是轻柔地释放的![foo doSomething]; //这将在上一行发布foo后崩溃。如果我们将getter改为:
-(Foo)foo {
return [[foo retain] autorelease];
}bar = [[bar alloc] init]; // bar的保留计数为1foo = bar.foo; // foo的保留计数为2(一个属于bar,一个属于自动释放池)。[bar release]; // Bar和所有它的象牙都是轻柔地释放的![foo doSomething]; //不会崩溃,因为foo仍然活着,并由自动释放池拥有。希望这解释了为什么应该始终从所有getter返回正确的自动释放对象。重要的是,任何返回值都能在它的父类被取消分配后存活下来,因为没有一个类能够保证客户端一旦暴露在野外时将如何处理它的值。
发布于 2010-10-24 16:10:13
保留,然后是自动发布,就像你可能认为的那样。它向对象发送retain消息,然后向其发送autorelease消息。请记住,自动释放对象会将该对象添加到自动释放池中,但尚未释放。自动释放池将在run循环当前迭代结束时向对象发送release消息。因此,后面跟着retain的autorelease本质上说,“确保这个对象一直保持到运行循环的当前迭代结束。”如果您需要返回的值停留更长时间,您可以保留它。如果没有,什么也不做,那么自动释放池就会处理它。
在这种情况下,发送的字符串retain和autorelease消息是一个属性。它已经被父对象保留了。因此,你可能会想,为什么这个保留和自动释放的东西呢?好的,不能保证在运行循环的当前迭代结束之前,对象不会释放_identifier。考虑一下这个例子:
- (NSString *)identifier { return _identifier; }
- (void)aMethod {
NSString *localId = [self identifier]; // localId refers to _identifier which is only retained by self
[self methodThatChangesIdentifierAndReleasesItsOldValue]; // self releases _identifier
NSLog(@"%@", localId); // crash, because localId (old value of _identifier) has been released
}在这种情况下,返回的标识符不会保留并自动释放。NSLog行崩溃是因为localId引用了已释放的字符串。但是,如果我们在getter中使用retain和autorelease,就不会出现崩溃,因为在运行循环的当前迭代结束之前,localId不会被释放。
据我所知,用identifier属性代替您将是一样好的。它可能不是相同的代码,但效果应该是相同的。
发布于 2010-10-24 16:17:15
苹果在实现访问器方法中很好地解释了这一点。如果调用方为标识符属性分配了一个新值,然后期望检索的值仍然可用,那么您引用的方法(由Apple引用的“Technology1”)有助于避免bug。大多数情况下都不需要它,但是仅仅返回ivar值就会导致很难找到的but。
https://stackoverflow.com/questions/4008940
复制相似问题