ARC下面的對象被釋放的bug


一般在ARC管理的方式之下,很難出現對象被過度釋放的問題,下面是我將遇到的一個crash。

* thread #1: tid = 0x31d1db, 0x0000000102e5e00b libobjc.A.dylib`objc_msgSend + 11, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x18)
    frame #0: 0x0000000102e5e00b libobjc.A.dylib`objc_msgSend + 11
    frame #1: 0x0000000101968212 UIKit`-[UISectionRowData refreshWithSection:tableView:tableViewRowData:] + 2353
    frame #2: 0x000000010196de45 UIKit`-[UITableViewRowData rectForFooterInSection:heightCanBeGuessed:] + 320
    frame #3: 0x000000010196df3a UIKit`-[UITableViewRowData heightForTable] + 56
    frame #4: 0x00000001017c0af0 UIKit`-[UITableView _updateContentSize] + 381
    frame #5: 0x00000001017ddecd UIKit`-[UITableView didMoveToWindow] + 65
    frame #6: 0x00000001017649a0 UIKit`-[UIView(Internal) _didMoveFromWindow:toWindow:] + 1482
    frame #7: 0x0000000101775333 UIKit`-[UIScrollView _didMoveFromWindow:toWindow:] + 55
    frame #8: 0x000000010176468e UIKit`-[UIView(Internal) _didMoveFromWindow:toWindow:] + 696
    frame #9: 0x000000010176468e UIKit`-[UIView(Internal) _didMoveFromWindow:toWindow:] + 696
    frame #10: 0x000000010176468e UIKit`-[UIView(Internal) _didMoveFromWindow:toWindow:] + 696
    frame #11: 0x000000010176468e UIKit`-[UIView(Internal) _didMoveFromWindow:toWindow:] + 696
    frame #12: 0x000000010175d112 UIKit`__45-[UIView(Hierarchy) _postMovedFromSuperview:]_block_invoke + 125
    frame #13: 0x000000010175d086 UIKit`-[UIView(Hierarchy) _postMovedFromSuperview:] + 437
    frame #14: 0x0000000101766f4b UIKit`-[UIView(Internal) _addSubview:positioned:relativeTo:] + 1604
    frame #15: 0x00000001017c816f UIKit`-[UITableView _addContentSubview:atBack:] + 245
    frame #16: 0x00000001017e08cd UIKit`__53-[UITableView _configureCellForDisplay:forIndexPath:]_block_invoke + 2403
    frame #17: 0x00000001017615ce UIKit`+[UIView(Animation) performWithoutAnimation:] + 65
    frame #18: 0x00000001017dff5b UIKit`-[UITableView _configureCellForDisplay:forIndexPath:] + 312
    frame #19: 0x00000001017e74cc UIKit`-[UITableView _createPreparedCellForGlobalRow:withIndexPath:willDisplay:] + 533
    frame #20: 0x00000001017c6fb1 UIKit`-[UITableView _updateVisibleCellsNow:isRecursive:] + 2846
    frame #21: 0x00000001017dce3c UIKit`-[UITableView layoutSubviews] + 213
    frame #22: 0x0000000101769973 UIKit`-[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 521
    frame #23: 0x00000001043efde8 QuartzCore`-[CALayer layoutSublayers] + 150
    frame #24: 0x00000001043e4a0e QuartzCore`CA::Layer::layout_if_needed(CA::Transaction*) + 380
    frame #25: 0x00000001043e487e QuartzCore`CA::Layer::layout_and_display_if_needed(CA::Transaction*) + 24
    frame #26: 0x000000010435263e QuartzCore`CA::Context::commit_transaction(CA::Transaction*) + 242
    frame #27: 0x000000010435374a QuartzCore`CA::Transaction::commit() + 390
    frame #28: 0x00000001016ee54d UIKit`-[UIApplication _reportMainSceneUpdateFinished:] + 44
    frame #29: 0x00000001016ef238 UIKit`-[UIApplication _runWithMainScene:transitionContext:completion:] + 2642
    frame #30: 0x00000001016edbf2 UIKit`-[UIApplication workspaceDidEndTransaction:] + 179
    frame #31: 0x000000010480c2a3 FrontBoardServices`__31-[FBSSerialQueue performAsync:]_block_invoke + 16
    frame #32: 0x00000001034f253c CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ + 12
    frame #33: 0x00000001034e8285 CoreFoundation`__CFRunLoopDoBlocks + 341
    frame #34: 0x00000001034e8045 CoreFoundation`__CFRunLoopRun + 2389
    frame #35: 0x00000001034e7486 CoreFoundation`CFRunLoopRunSpecific + 470
    frame #36: 0x00000001016ed669 UIKit`-[UIApplication _run] + 413
    frame #37: 0x00000001016f0420 UIKit`UIApplicationMain + 1282
  * frame #38: 0x0000000101513903 NiuHelper`main(argc=1, argv=0x00007fff5e7ac350) + 115 at main.m:14
    frame #39: 0x000000010844d145 libdyld.dylib`start + 1

看問題還以為是蘋果的bug,搜索一番之后看到一個人遇到同樣的問題,一個網友給出的回復是:

Sorry I never came back to this thread.

So the issue is that this nib is being loaded by a view controller through its initWithNibName:bundle: method. That method will not retain any top level objects on its own.

So your Highscore Controller object is loaded from the nib and then autoreleased, which means it goes away pretty quickly after that. So you need to retain that object. One easy way to do that is to define a property in your view controller subclass for this object (specifying 'retain' and 'IBOutlet' of course) and then connect that outlet to this Highscore Controller in IB.

聯想到自己這里創建了一個VC,將VC的view添加到界面中就沒有管這個VC了,VC被釋放,看來要好好注意這種autorelease的問題了,即使是在同一個線程中還是可能存在問題。

- (TopTabPage *)TopTabControl:(TopTabControl *)tabCtrl
                  pageAtIndex:(NSUInteger)index
{
    TopTabPage *page = [[TopTabPage alloc] initWithFrame:CGRectMake(0,
                                                                    0,
                                                                    CGRectGetWidth(self.view.frame),
                                                                    CGRectGetHeight(tabCtrl.bounds) -  30
                                                                    )];
    
    
    
    NHNewsModel *NewsModel = [self.tagListModel.result.channelList objectAtIndex:index];
    NHNewsContentViewController *contentViewVC = [[NHNewsContentViewController alloc] initWithChannelID:NewsModel.getChannelID
                                                                                         andContentRect:page.bounds];
    [page addSubview:contentViewVC.view];
    
//    [_array addObject:contentViewVC];
    return page;
}

將VC retain之后就沒有問題了。蘋果的arc也不能完全相信啊。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM