从后台返回时 viewDidLoad 崩溃
我最近使用一个应用程序启用了多任务处理(后台运行时不会退出),现在用户会在不可预测的时间崩溃。崩溃日志显示崩溃发生在 viewDidLoad 中。
无论如何,我的 viewDidLoad 方法可能需要重新考虑。我从 xib 加载了一些视图,然后以编程方式构建层次结构的其余部分(包括一些自动释放的 UIButton,我认为这是崩溃的罪魁祸首)。对可能发生的事情以及如何更好地解决这个问题有什么见解吗?
这是一个典型的崩溃报告:
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x49ef527e
Crashed Thread: 0
Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0 libobjc.A.dylib 0x32da1c9a objc_msgSend + 18
1 App 0x0000a890 -[EntryViewController viewDidLoad] (EntryViewController.m:270)
2 UIKit 0x3241ff08 -[UIViewController view] + 104
3 UIKit 0x3242c1ce -[UIViewController viewControllerForRotation] + 34
4 UIKit 0x3242ca40 -[UIViewController shouldWindowUseOnePartInterfaceRotationAnimation:] + 8
5 UIKit 0x3242c9a8 -[UIWindow _clientsForRotation] + 236
6 UIKit 0x32494fea -[UIWindow _setRotatableClient:toOrientation:updateStatusBar:duration:force:] + 70
7 UIKit 0x32493f9e -[UIWindowController transition:fromViewController:toViewController:target:didEndSelector:] + 946
8 UIKit 0x324bec50 -[UIViewController _dismissModalViewControllerWithTransition:from:] + 1444
9 UIKit 0x324be5e0 -[UIViewController dismissModalViewControllerWithTransition:] + 596
10 UIKit 0x324be366 -[UIViewController dismissModalViewControllerAnimated:] + 86
最有帮助的是快速概述在加载/卸载周期中管理视图层次结构的最佳实践。我知道 IBOutlet 应该保留在 viewDidUnload 中设置为 nil 的属性。
但是以编程方式创建的 UIView 和 UIControl 又如何呢?可以在 viewDidLoad 中创建一个本地对象,将其添加到视图中,然后释放它,再也不用担心它了吗?可以在 ivars 中使用分配初始化的视图,直到释放为止我不会释放它吗?可以使用我从未发布过的自动发布视图吗?
这是我的一些 viewDidLoad:
imagebg = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"background.png"]];
[self.view addSubview:imagebg];
[self positionBackgroundAt:0];
UIButton *flickbtn = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
[flickbtn addTarget:self action:@selector(flick:) forControlEvents:UIControlEventValueChanged];
[self.view addSubview:flickbtn];
[flickbtn release];
// SET UP UPPER LEFT BUTTONS
upperLeftButton0 = [UIButton buttonWithType:UIButtonTypeCustom];
[upperLeftButton0 setFrame:CGRectZero];
[self.view addSubview:upperLeftButton0];
upperLeftButton1 = [UIButton buttonWithType:UIButtonTypeCustom];
[upperLeftButton1 setFrame:CGRectZero];
[self.view addSubview:upperLeftButton1];
// SET UP DISPLAY
displayimg = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"newdisplay.png"]];
[displayimg setCenter:CGPointMake(CGRectGetMidX(self.view.frame),CGRectGetMaxY(self.view.frame) - 57)];
[self.view addSubview:displayimg];
[displayimg release];
...
我的 viewDidUnload 只是将所有 IBOutlet 设置为 nil。
谢谢。
I recently enabled multitasking with an app (doesn't exit when backgrounded) and now have users getting crashes at unpredictable times. The crash logs show the crashes occur in viewDidLoad.
My viewDidLoad approach probably needs rethinking anyway. I have some of the view loaded from the xib, then I build the rest of the hierarchy programmatically (including some autoreleased UIButton's, which I think are the crashing culprit). Any insight into what could be going on and how to approach this better?
Here's a typical crash report:
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x49ef527e
Crashed Thread: 0
Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0 libobjc.A.dylib 0x32da1c9a objc_msgSend + 18
1 App 0x0000a890 -[EntryViewController viewDidLoad] (EntryViewController.m:270)
2 UIKit 0x3241ff08 -[UIViewController view] + 104
3 UIKit 0x3242c1ce -[UIViewController viewControllerForRotation] + 34
4 UIKit 0x3242ca40 -[UIViewController shouldWindowUseOnePartInterfaceRotationAnimation:] + 8
5 UIKit 0x3242c9a8 -[UIWindow _clientsForRotation] + 236
6 UIKit 0x32494fea -[UIWindow _setRotatableClient:toOrientation:updateStatusBar:duration:force:] + 70
7 UIKit 0x32493f9e -[UIWindowController transition:fromViewController:toViewController:target:didEndSelector:] + 946
8 UIKit 0x324bec50 -[UIViewController _dismissModalViewControllerWithTransition:from:] + 1444
9 UIKit 0x324be5e0 -[UIViewController dismissModalViewControllerWithTransition:] + 596
10 UIKit 0x324be366 -[UIViewController dismissModalViewControllerAnimated:] + 86
What would be most helpful is a quick rundown on best practices for managing the view hierarchy across the load/unload cycle. I know IBOutlet's should be retained properties that get set to nil in viewDidUnload.
But what about programmatically created UIView's and UIControl's? Ok to create a local object in viewDidLoad, add it to the view, and release it, never worrying about it again? Ok to use alloc-init'ed views in ivars that I don't release till dealloc? Ok to use autoreleased views that I never release?
Here's some of my viewDidLoad:
imagebg = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"background.png"]];
[self.view addSubview:imagebg];
[self positionBackgroundAt:0];
UIButton *flickbtn = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
[flickbtn addTarget:self action:@selector(flick:) forControlEvents:UIControlEventValueChanged];
[self.view addSubview:flickbtn];
[flickbtn release];
// SET UP UPPER LEFT BUTTONS
upperLeftButton0 = [UIButton buttonWithType:UIButtonTypeCustom];
[upperLeftButton0 setFrame:CGRectZero];
[self.view addSubview:upperLeftButton0];
upperLeftButton1 = [UIButton buttonWithType:UIButtonTypeCustom];
[upperLeftButton1 setFrame:CGRectZero];
[self.view addSubview:upperLeftButton1];
// SET UP DISPLAY
displayimg = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"newdisplay.png"]];
[displayimg setCenter:CGPointMake(CGRectGetMidX(self.view.frame),CGRectGetMaxY(self.view.frame) - 57)];
[self.view addSubview:displayimg];
[displayimg release];
...
My viewDidUnload just sets all IBOutlets to nil.
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果没有您的代码和由此产生的错误,这是我对可能的内存问题的最佳建议:首先,使用“产品”菜单中的“分析”功能,并解决引发的所有警告。如果问题仍然存在,请对其进行分析并使用分配或泄漏分析器来跟踪您的内存。最后,调试有问题的部分并查看内存堆栈,以了解与应用程序崩溃时相比,viewDidLoad 中实际存在的内容。最近,我不小心在我的一个属性中使用了分配而不是保留,并最终遇到了类似的问题。如上所述,请确保将释放的对象设置为零。释放和消除保留属性的最快方法是:
Without your code and resulting error, here is my best suggestion for probable memory issues: First, use the "Analyze" function from the "Product" menu, and resolve all warnings raised. If you still have the issue, profile it and use the allocation or leak profiler to track your memory. Finally, debug sections that are having issues and view the memory stack to see what is actually there in viewDidLoad as compared to when the application crashes. Recently I accidentally used assign instead of retain in one of my properties and ended up with a similar issue. As stated above, make sure to set nil your released objects. The quickest way to release and nillify retained properties is: