自动释放范围

时间:2009-02-24 13:57:15

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

我想知道iPhone上的autorelese是如何工作的。我发现,一旦你向对象发送自动释放,就可以保留,直到阻止autorelease块的范围结束。这是对的吗?

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

    (void)applicationDidFinishLaunching:(UIApplication *)application {

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

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

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

现在,一旦我从控制器初始化中删除了autorelease,所有内容都会从那里顺利进行。

这是关于什么的?

干杯, ķ。

4 个答案:

答案 0 :(得分:13)

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

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

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

答案 1 :(得分:4)

为了扩展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 :(得分:0)

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

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

答案 3 :(得分:0)

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