自动释放范围

我想知道自动删除是如何在iPhone上运行的。 我发现,一旦你向一个对象发送一个自动释放, 它就会被保留,直到块的范围结束autorelease发送autorelease 。 那是对的吗?

我在applicationDidFinishLaunching初始化来自NIB的视图,如下所示:

  (void)applicationDidFinishLaunching:(UIApplication *)application { loginViewController = [[[LoginViewController alloc] initWithNibName:@"LoginView" bundle:nil] autorelease]; [window addSubview: [loginViewController view]]; [window makeKeyAndVisible]; } 

并且视图根本没有显示,屏幕上的所有内容都是UIWindow

现在,一旦我从控制器初始化中删除了autorelease ,所以从那里开始顺利进行。

这是关于什么的?

干杯,K。

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

当您将LoginViewController所有权授予自动释放池时,它会在applicationDidFinishLaunching:返回后立即释放。 当视图控制器释放自身时,它会从superview(在这种情况下是你的窗口)中删除它的视图。

您的应用程序委托应该保留LoginViewController所有权并在app delegate的dealloc方法中release它(或者当您完成登录并转移到另一个视图时)。

为了扩展Don的答案,说“你将对象的所有权授予当前的自动释放池”可能有些令人困惑。 这可能被误解为意味着在自动释放池耗尽时保证对象被销毁。 这是不正确的(尽管在这种情况下会发生)。 发送-autorelease请求自动释放池在耗尽时发送-autorelease消息。 如果-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]; } 

在runloop结束时清理autoreleasepool。 这意味着只要您调用方法并执行操作,它仍然存在。

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

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