我想知道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
,所有内容都会从那里顺利进行。
这是关于什么的?
干杯, ķ。
答案 0 :(得分:13)
当您致电autorelease
时,您将该对象的所有权授予当前的自动释放池。运行循环在调度事件(例如applicationDidFinishLaunching:
)之前创建一个新的自动释放池,并在事件结束时销毁该池。
当您将LoginViewController
的所有权授予自动释放池时,它会在applicationDidFinishLaunching:
返回后立即释放。当视图控制器解除分配时,它会从superview(在这种情况下是你的窗口)中删除它的视图。
您的应用程序代表应该在应用委托的LoginViewController
方法中保留release
和dealloc
的所有权(或者当您完成登录并转到另一个视图时) )。
答案 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
添加到自动释放池,因此它将在运行循环结束时释放。当发生这种情况时,它还会释放其视图并将其从显示中删除。