视图控制器被发送消息,即使它已被释放 [英] View Controller being sent a message even though it has been deallocated

查看:22
本文介绍了视图控制器被发送消息,即使它已被释放的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不确定 iPhone SDK 3.0 中是否发生了一些变化,但我收到了最奇怪的错误.我有一个视图控制器层次结构,我根据界面方向在视图控制器之间切换.据我所知,每当我旋转界面时都会导致错误,已释放的视图控制器正在发送 shouldAutorotateToInterfaceOrientation 消息.这是错误的回溯:

I am not sure if something has changed in the iPhone SDK 3.0 but I am getting the strangest error. I have a view controller hierarchy where I switch between view controllers depending upon interface orientation. From what I can tell, the error is caused whenever I rotate the interface a view controller which has been deallocated is being sent a shouldAutorotateToInterfaceOrientation message. This is the backtrace for the error:

#0 0x01dc43a7 in ___forwarding___
#1 0x01da06c2 in __forwarding_prep_0___
#2 0x002e6733 in -[UIWindow _shouldAutorotateToInterfaceOrientation:]
#3 0x002e6562 in -[UIWindow _updateToInterfaceOrientation:duration:force:]
#4 0x002e6515 in -[UIWindow _updateInterfaceOrientationFromDeviceOrientation]
#5 0x0004d63a in _nsnote_callback
#6 0x01d8f005 in _CFXNotificationPostNotification
#7 0x0004aef0 in -[NSNotificationCenter postNotificationName:object:userInfo:]
#8 0x0045b454 in -[UIDevice setOrientation:]
#9 0x002d6890 in -[UIApplication handleEvent:withNewEvent:]
#10 0x002d16d3 in -[UIApplication sendEvent:]
#11 0x002d80b5 in _UIApplicationHandleEvent
#12 0x024c2ef1 in PurpleEventCallback
#13 0x01d9bb80 in CFRunLoopRunSpecific
#14 0x01d9ac48 in CFRunLoopRunInMode
#15 0x024c17ad in GSEventRunModal
#16 0x024c1872 in GSEventRun
#17 0x002d9003 in UIApplicationMain
#18 0x00002d50 in main at main.m:14

使用 NSZombieEnabled 打印到调试控制台的错误是:

The error that is getting printed to the Debug Console with NSZombieEnabled is:

2009-10-18 20:28:34.404 Restaurants[12428:207] *** -[ToolbarController respondsToSelector:]: message sent to deallocated instance 0x3b2b2a0
(gdb) continue
Current language:  auto; currently objective-c
2009-10-18 20:31:43.496 Restaurants[12428:207] *** NSInvocation: warning: object 0x3b2b2a0 of class '_NSZombie_BeltToolbarController' does not implement methodSignatureForSelector: -- trouble ahead
2009-10-18 20:31:43.496 Restaurants[12428:207] *** NSInvocation: warning: object 0x3b2b2a0 of class '_NSZombie_BeltToolbarController' does not implement doesNotRecognizeSelector: -- abort

我无法理解的是,即使控制器已被解除分配,系统仍会尝试向该控制器发送消息,并且有没有办法告诉系统控制器不再存在.

What I can't understand is why the system is trying to message this controller even though it has been deallocated and is there a way to tell the system that the controller doesn't exist any longer.

[更新]:我整理了一个复制错误的示例项目:download

[UPDATE]: I have put together a sample project replicating the bug: download

加载应用程序,然后将模拟器的方向从横向更改为纵向几次,它应该会发生.我已经在实体手机上尝试了相同的代码,它的行为方式完全相同,所以这不是模拟器相关的问题.

Load up the app and then change the Simulator's orientation a few times from Landscape to Portrait and it should occur. I have tried the same piece of code on a physical phone and it behaves in exactly the same way, so this is not a simulator related issue.

[更新]:我已经用完了我向 Apple 技术团队提出的一项支持请求,看看他们是否可以帮助我找到问题的根源.将发布解决方案 - 如果他们有 - 在这里.感谢到目前为止的帮助.

[UPDATE]: I have used up one of my support requests with Apple's technical team to see if they can help me get to the bottom of this. Will post the solution - if they have one - here. Thanks for the help so far.

推荐答案

所以经过一周的等待,Apple Developer Technical Support 设法帮助我解决了我的问题.这是他们的回应:

So after a week of waiting, Apple Developer Technical Support managed to help me sort my problem out. Here is their response:

"我查看了你的代码,发现您需要关注的几件事大约,其中一些可能有助于你的问题.在你的ControllerSwitchAppDelegate.m来源,您正在实施didRotate"方法.有可能值得检查设备方向视图控制器的通知级别而不是在 UIApplication等级.这将使您的代码很多更简单和封装允许显示的每个视图控制器处理自己的旋转逻辑.你也在使用多视图同时,控制器是,两个视图"属性都是当设备被添加和移除时被旋转.这不完全是使用的常用方法UIKit.这个想法是提出一个视图控制器(或其视图属性)一次并且没有父视图控制器在不同的子视图中交换控制器.表面上授予你的方法似乎可行,但在从长远来看,我推荐一个不同的方法.

"I've looked over your code and found a few things you need to be concerned about, some of which may contribute to your problem. In your ControllerSwitchAppDelegate.m source, you are implementing "didRotate" method. It might be worth checking for device orientation notifications at the view controller level rather than at the UIApplication level. This will make your code much more simpler and encapsulated allowing each view controller that is shown to handle its own rotation logic. You are also using multiple view controllers at the same time, that being, both "view" properties are being added and remove when the device is rotated. This is not exactly the common approach in which to use the UIKit. The idea is to present one view controller (or its view property) at a time and not have a parent view controller swap in different sub-view controllers. Granted on the surface your approach seems doable, but in the long run, I recommend a different approach.

我们有一个名为AlternateViews",可以找到在 -http://developer.apple.com/iphone/library/samplecode/AlternateViews/index.html

We have a sample called "AlternateViews", which can be found at - http://developer.apple.com/iphone/library/samplecode/AlternateViews/index.html

在这个示例中,它几乎做到了你需要什么.它提供了一个替代"视图控制器给定的设备方向.仅仅是呈现一个视图控制器另一个使用presentModalViewController"与称为过渡属性modalTransitionStyle"这将给出你是一个淡入淡出的影响."

In this sample, it pretty much does what you need. It provides an "alternate" view controller for a given device orientation. Is merely presents one view controller over another using "presentModalViewController" with a transition property called "modalTransitionStyle" which will give you a cross fade affect."

我最终做的是使用一个超级视图控制器来呈现和关闭视图控制器.而不是使用 AppDelegate 交换视图控制器和删除子视图.

What I ended up doing was using a super view controller that presented and dismissed view controllers. Rather than swapping view controllers and removing sub views using the AppDelegate.

这篇关于视图控制器被发送消息,即使它已被释放的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆