从后台返回时 viewDidLoad 崩溃

发布于 2024-11-28 12:29:53 字数 2959 浏览 2 评论 0原文

我最近使用一个应用程序启用了多任务处理(后台运行时不会退出),现在用户会在不可预测的时间崩溃。崩溃日志显示崩溃发生在 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

维持三分热 2024-12-05 12:29:53

如果没有您的代码和由此产生的错误,这是我对可能的内存问题的最佳建议:首先,使用“产品”菜单中的“分析”功能,并解决引发的所有警告。如果问题仍然存在,请对其进行分析并使用分配或泄漏分析器来跟踪您的内存。最后,调试有问题的部分并查看内存堆栈,以了解与应用程序崩溃时相比,viewDidLoad 中实际存在的内容。最近,我不小心在我的一个属性中使用了分配而不是保留,并最终遇到了类似的问题。如上所述,请确保将释放的对象设置为零。释放和消除保留属性的最快方法是:

self.myProperty = nil;

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:

self.myProperty = nil;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文