非常奇怪的崩溃,可能与ARC有关并且只出现在iPhone 5s上

时间:2014-05-19 18:28:29

标签: ios memory-management

Thread : Crashed: com.apple.main-thread
0  libobjc.A.dylib                0x000000019a5639d0 objc_msgSend + 16
1  UIKit                          0x00000001915af1d0 -[UISearchDisplayController _cleanUpSearchBar] + 196
2  UIKit                          0x00000001915af0a0 -[UISearchBar willMoveToSuperview:] + 68
3  UIKit                          0x0000000191788ea4 __UIViewWillBeRemovedFromSuperview + 192
4  UIKit                          0x00000001914b83f4 -[UIView(Hierarchy) removeFromSuperview] + 72
5  UIKit                          0x00000001914bb4fc -[UIView dealloc] + 424
6  UIKit                          0x000000019159f354 -[UIScrollView dealloc] + 972
7  UIKit                          0x000000019165fc40 -[UITableView dealloc] + 1304
8  UIKit                          0x000000019159ed60 -[UIScrollView removeFromSuperview] + 80
9  UIKit                          0x00000001914bb4fc -[UIView dealloc] + 424
10 UIKit                          0x000000019165010c -[UIViewController dealloc] + 464
11 Gogobot                        0x000000010017e560 -[GBListPageViewController dealloc] (GBListPageViewController.m:288)
12 Gogobot                        0x0000000100189f84 __destroy_helper_block_982 (GBListPageViewController.m)
13 libsystem_blocks.dylib         0x000000019ab7f908 _Block_release + 256
14 libsystem_blocks.dylib         0x000000019ab7f908 _Block_release + 256
15 libsystem_blocks.dylib         0x000000019ab7f908 _Block_release + 256
16 Foundation                     0x000000018f198b78 __destroy_helper_block_165 + 28
17 libsystem_blocks.dylib         0x000000019ab7f908 _Block_release + 256
18 Foundation                     0x000000018f0a138c -[NSBlockOperation dealloc] + 68
19 libdispatch.dylib              0x000000019ab383e0 _dispatch_client_callout + 16
20 libdispatch.dylib              0x000000019ab3b56c _dispatch_main_queue_callback_4CF + 344
21 CoreFoundation                 0x000000018e5aad64 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 12
22 CoreFoundation                 0x000000018e5a90a4 __CFRunLoopRun + 1452
23 CoreFoundation                 0x000000018e4e9b38 CFRunLoopRunSpecific + 452
24 GraphicsServices               0x0000000193f0f830 GSEventRunModal + 168
25 UIKit                          0x00000001915280e8 UIApplicationMain + 1156
26 Gogobot                        0x0000000100202c20 main (main.m:16)
27 libdyld.dylib                  0x000000019ab53aa0 start + 4

以下是我从crashlytics获得的崩溃日志。从这两行看来,dealloc似乎有些不对,

11 Gogobot                        0x000000010017e560 -[GBListPageViewController dealloc] (GBListPageViewController.m:288)
12 Gogobot  

但是我使用ARC,甚至没有在dealloc中实现任何东西。当我测试时,它永远不会发生在我身上,但我们从Crashlytcis获得了相同的崩溃报告,每天10-20次。有些用户有30%的免费ram。看起来不像是内存问题。但所有报告都来自iPhone 5s。

我一直试图在我的iphone 5s和5上重现它。根本无法再创造......任何想法都会受到赞赏。

这是我的GBListPageViewController中的dealloc:

- (void)dealloc
{
    [[NSNotificationCenter defaultCenter]removeObserver:self name:kGBListPageVCSortSelected object:nil];
    [[NSNotificationCenter defaultCenter]removeObserver:self name:UIApplicationWillEnterForegroundNotification object:nil];
}

=============================================== =======================

新编辑:

我们尝试在dealloc中删除委托和观察者,但似乎并没有解决问题。从我们的崩溃报告中,似乎所有的崩溃都发生在iphone5s + 7.0.x操作系统上。

这是我们用来删除委托的代码,非常简单。

- (void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    self.searchDisplayController.searchBar.delegate = nil;
    self.searchDisplayController.delegate = nil;
}

任何人都有同样的问题吗?...

2 个答案:

答案 0 :(得分:1)

我的赌注是视图控制器在视图之前被释放,而视图仍然有对该委托的引用并尝试调用委托方法。我在iOS 7.X中看到过很多这样的内容。

设置搜索栏,并在视图控制器的dealloc中将显示控制器的代表搜索到nil

答案 1 :(得分:1)

我也遇到过这个问题。我的解决方法相当不正统;在segue的目标视图控制器中,我设置了一个属性来保存指向源视图控制器的指针,然后在viewWillAppear:animated中将其设置为nil。就像我说的那样,它是非正统的,但是它有效,给源视图控制器足够的时间来清理它,然后再解除分配。

编辑:

@property (nonatomic, strong) id vcToHoldForARCDeallocBug; 

- (void)viewDidAppear:(BOOL)animated { 
     [super viewDidAppear:animated]; 
     self.vcToHoldForARCDeallocBug = nil; 
} 

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {     
     self.vcToHoldForARCDeallocBug = segue.destinationViewController; 
}

它在显示时设置指向目标视图控制器的指针。一旦用户导航回来,在viewDidAppear中它会清除指针并允许ARC取消分配目标视图控制器,因为在调用viewDidAppear时已清理了所有内容。