说真的,这个问题让同事卡了许久。同事的App有一个怪现象,用ImagePickerController打开相机后,不管照不照相,一关闭ImagePickerController同时旋转屏幕就闪退(不旋屏则没事)。
同事是iOS新手,来求教于我。我搜遍Google,只发现了一个一样的例子:
http://www.cocoachina.com/bbs/read.php?tid=232792&page=e&#a
但是并没有现成的答案。
笔者起先以为是UIImagePickerController使用上的问题,在StackOverFlow上搜了一堆稍微沾点边的答案(起码试了一百个答案),但除了白白浪费掉十多个小时的时间外,没有一点作用。
没有一点明显的错误提示,僵尸变量、符号断点也无效。并且每次的错误信息都不一样,没有任何规律可言。只是最后有一个Bad Exec错误,感觉有点象内存管理失败。
无奈之下逐行查看 View Controller 代码,终于发现了问题。在viewWillAppear方法中,有如下代码:
NSNotificationCenter.defaultCenter().addObserver(self,selector: "keyboardShow:", name: UIKeyboardWillShowNotification,object: nil)
NSNotificationCenter.defaultCenter().addObserver(self,selector: "keyboardHide:", name: UIKeyboardWillHideNotification,object: nil)
NSNotificationCenter.defaultCenter().addObserver(self,selector: "ActionGoPushDidRecieveMessage:", name:"GoPushRecieveMessage", object: nil)
NSNotificationCenter.defaultCenter().addObserver(self,selector: "ActionAPNSDidRecieveMessage:", name:"APNSRecieveMessage", object: nil)
而注销通知中心的代码却放在了viewDidDisappear方法中。这不出问题才怪。于是将这堆代码移到了viewDidLoad方法。然后在deinit方法中:
NSNotificationCenter.defaultCenter().removeObserver(self)
问题解决。显然这个问题跟ImagePickerController 一点关系没有。在ImagePickerController解散后,原来的View Controller的viewWillAppear方法被调用,由于程序员进行了不平衡的调用(viewWillAppear的平衡方法应该是viewWillDisappear方法而不是viewDidDisappear方法),引起内存管理失败,程序crash。
这个教训告诉我们:不按规范编写代码会导致什么样的恶果。
补充:同样的问题还出现在 viewDidLoad方法中使用了UIAlertController,将代码删除解决问题。