【问题标题】:Autorelease scope自动释放范围
【发布时间】:2010-10-09 13:42:11
【问题描述】:

我想知道 autorelese 如何在 iPhone 上工作。我认为,一旦您向对象发送自动释放,保证会一直保留到块范围的末尾,autorelease 已发送。对吗?

我正在从 applicationDidFinishLaunching 中的 NIB 初始化一个视图,如下所示:

    (void)applicationDidFinishLaunching:(UIApplication *)application {

    loginViewController = [[[LoginViewController alloc] initWithNibName:@"LoginView" bundle:nil] autorelease];

    [window addSubview: [loginViewController view]];
    [window makeKeyAndVisible];
}

视图根本没有显示,屏幕上只有UIWindow

现在,一旦我从控制器初始化结束时删除了autorelease,一切都从那里开始顺利。

这是怎么回事?

干杯, K.

【问题讨论】:

    标签: ios objective-c xcode cocoa cocoa-touch


    【解决方案1】:

    为了扩展 Don 的答案,说“您将对象的所有权授予当前自动释放池”可能会有些混乱。这可能会被误解为当自动释放池耗尽时,对象肯定会被销毁。这是不正确的(尽管在这种情况下会发生)。发送-autorelease 请求自动释放池在耗尽时发送-release 消息。如果该-release 消息使retainCount = 0,则该对象将被销毁。

    因此,为了执行 Don 的建议,您需要创建一个 ivar 来跟踪此视图控制器。他对视图为何消失的解释是完全正确的;但你不想只是泄漏视图控制器。你想抓住它,当你完成它时释放它。

    @interface ... {
       LoginViewController *_loginViewController;
    }
    
    @property (readwrite, retain) LoginViewController *loginViewController;
    
    @implementation ...
    @synthesize loginViewController = _loginViewController;
    
    - (void)applicationDidFinishLaunching:(UIApplication *)application {
    
        self.loginViewController = [[[LoginViewController alloc] initWithNibName:@"LoginView" bundle:nil] autorelease];
    
        [window addSubview: [loginViewController view]];
        [window makeKeyAndVisible];
    }
    
    - (void)dealloc {
        [_loginViewController release]; _loginViewController = nil;
        [super dealloc];
    }
    

    【讨论】:

      【解决方案2】:

      当您调用autorelease 时,您将对象的所有权授予当前自动释放池。运行循环在调度事件(例如applicationDidFinishLaunching:)之前创建一个新的自动释放池,并在事件完成时销毁该池。

      当您将 LoginViewController 的所有权授予自动释放池时,它会在 applicationDidFinishLaunching: 返回后立即释放。当视图控制器释放自己时,它会从超级视图(在本例中为您的窗口)中删除其视图。

      您的应用程序委托应在应用程序委托的dealloc 方法中(或者当您完成登录并移至另一个视图时)保留LoginViewControllerrelease 的所有权。

      【讨论】:

        【解决方案3】:

        由于您将LoginViewController 添加到自动释放池中,因此它会在运行循环结束时被释放。发生这种情况时,它还会释放其视图并将其从显示中移除。

        【讨论】:

        • 视图应该被窗口保留。 (虽然我无权访问文档。)
        • 但是当视图控制器被释放时,它会从它的父视图中移除它所管理的视图。
        【解决方案4】:

        自动释放池在运行循环结束时被清理。这意味着只要您调用方法并执行操作,它就仍然存在。

        我没有在您的代码中看到错误,但在您的示例中正确保留了 Window。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2010-11-26
          • 1970-01-01
          • 2012-05-15
          • 2011-11-09
          • 2011-05-03
          • 1970-01-01
          • 2020-12-11
          相关资源
          最近更新 更多