'myObj = [[[[MyClass alloc] init] autorelease]的效果保留];'?

时间:2010-08-31 20:03:42

标签: iphone objective-c facebook memory-management

我刚刚下载了Facebook iOS SDK,我注意到在SDK附带的示例代码中,只要它创建了一个Facebook类的实例,就会这样:

_facebook = [[[[Facebook alloc] init] autorelease] retain];

其中_facebook是调用对象的成员变量(即不是局部变量)。

任何人都可以确切地解释自动释放的重点是什么,然后保留它?

2 个答案:

答案 0 :(得分:13)

除了消耗一些周期和记忆之外,它实际上没有任何作用。

或者更确切地说,在正确编写的应用程序中,它什么都不做。在错误编写的应用程序中,它可能会通过延长_facebook对象的生命周期来掩盖错误。但是,这不是一个真正的解决方案。

我在http://github.com/facebook/facebook-ios-sdk/blob/master/sample/DemoApp/Classes/DemoAppViewController.m中找到了类似的代码行。如果那就是你所指的那样,是的,这是无稽之谈。

答案 1 :(得分:1)

虽然你发现的代码可能只是草率,但这种模式有意义。

“alloc,autorelease,retain”意味着该对象在两个地方被引用:

  • 作为调用堆栈的返回值(自动释放样式)
  • 通过FB SDK本身('保留')

如果两个引用可以独立发布,这很重要。例如,如果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];
}
相关问题