Apple在实例变量mainSprocket:
的setter方法中执行此操作– (void)setMainSprocket:(Sprocket *)newSprocket {
[mainSprocket autorelease];
mainSprocket = [newSprocket retain];
return;
}
为什么他们发送-autorelease而不是-release?这是一个不好的效果吗?实际上它不应该(因为我的理解),因为-release只是说实例变量mainSprocket持有的当前对象不再被该实例变量使用。对于其他人仍然对该对象仍然感兴趣的情况,该方法可以保留它,对吧?那么 - 发布应该没事,我想?
答案 0 :(得分:4)
如果mainSprocket
和newSprocket
是同一个对象,那么如果您使用简单的release
,它就会被释放。
如果您不想使用autorelease
,请使用:
– (void)setMainSprocket:(Sprocket *)newSprocket {
// if newSprocket and mainSprocket were the same object,
// it would first be retained and then released
// and therefore not deleted.
[newSprocket retain];
[mainSprocket release];
mainSprocket = newSprocket;
// you don't need return in a void-method
// return;
}
你为什么不使用房产?它们是Objective-C 2.0的实现方式。
<强> SomeObject.h 强>
@interface SomeObject : NSObject {
Sprocket *mainSprocket;
}
@property(retain) Sprocket *mainSprocket;
@end
<强> SomeObject.m 强>
@implementation SomeObject
@synthesize mainSprocket;
@end
答案 1 :(得分:3)
如果autorelease
和newSprocket
碰巧是同一个对象,他们会在mainSprocket
进行此操作。调用release
可能会无意中释放对象,然后才能将其保留在下一行,而autorelease
将不会被处理,直到自动释放池在事件循环结束时耗尽。< / p>
考虑这种情况:
Sprocket *mySprocket = [Sprocket spacelySprocket];
[sprocketManager setMainSprocket:mySprocket];
Sprocket *anotherPointerToMySprocket = mySprocket;
[sprocketManager setMainSprocket:anotherPointerToMySprocket];
如果mainSprocket
未自动释放,则最后一行会导致问题。您可能有时会看到执行相同操作的setter代码的另一个约定是:
– (void)setMainSprocket:(Sprocket *)newSprocket {
if (newSprocket != mainSprocket) {
[mainSprocket release];
mainSprocket = [newSprocket retain];
}
}
我会让其他人评论哪个更合适或更美观: - )