我刚刚下载了Facebook iOS SDK,我注意到在SDK附带的示例代码中,只要它创建了一个Facebook类的实例,就会这样:
_facebook = [[[[Facebook alloc] init] autorelease] retain];
其中_facebook
是调用对象的成员变量(即不是局部变量)。
任何人都可以确切地解释自动释放的重点是什么,然后保留它?
答案 0 :(得分:13)
除了消耗一些周期和记忆之外,它实际上没有任何作用。
或者更确切地说,在正确编写的应用程序中,它什么都不做。在错误编写的应用程序中,它可能会通过延长_facebook
对象的生命周期来掩盖错误。但是,这不是一个真正的解决方案。
我在http://github.com/facebook/facebook-ios-sdk/blob/master/sample/DemoApp/Classes/DemoAppViewController.m中找到了类似的代码行。如果那就是你所指的那样,是的,这是无稽之谈。
答案 1 :(得分:1)
虽然你发现的代码可能只是草率,但这种模式有意义。
“alloc,autorelease,retain”意味着该对象在两个地方被引用:
如果两个引用可以独立发布,这很重要。例如,如果SDK可以在调用堆栈完成之前释放其引用并耗尽自动释放池。好的,这非常微妙;我是什么意思?
考虑以下情况:
A)实际代码
_facebook = [[[[Facebook alloc] init] autorelease] retain];
_facebook现在有一个保留计数为2,并且预计会有2次调用'release':1来自任何一个名为“retain”的人,以及将来某个时候NSAutoreleasePool消耗的时间为1。 < / p>
B)提出的简单“替代”(非等效)
_facebook = [[Facebook alloc] init];
_facebook的保留计数为1,并且在调用“release”时将被销毁(如果自动释放池尚未耗尽并且调用堆栈仍在使用该对象,则可能是一个大问题)
为什么这很重要?想象一下这样的代码:
@implementation (Thinger)
+(id) make_new_thing
{
return my_copy_of_thing = [[[[Thing alloc] init] autorelease] retain];
}
+(id) forget_about_thing
{
if (my_copy_of_thing != nil) {
[my_copy_of_thing release];
my_copy_of_thing = nil;
}
}
@end
void foo() {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
id thing = [Thinger make_new_thing];
[Thinger forget_about_thing];
...
[thing useThing]; // implementation B would break here !
[pool drain];
}