在自定义 UITableViewHeaderFooterView
的子类中, 使用名称为 sectionHeader
的属性,属性描述是 strong
,那么会造成崩溃
崩溃线程的调用堆栈截图如下:
使用 thread backtrace
命令打印当前线程情况:
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x1)
* frame #0: 0x00000001806e8198 libobjc.A.dylib`objc_retain + 8
frame #1: 0x00000001806e8218 libobjc.A.dylib`objc_storeStrong + 44
frame #2: 0x000000010415257c anchorplatform`-[QFLearnHistoryHeaderView setSectionHeader:](self=0x00000001570069b0, _cmd="setSectionHeader:", sectionHeader=0x0000000000000001) at QFLearnHistoryHeaderView.m:0
frame #3: 0x000000018b377998 UIKit`-[UITableView _setupSectionView:isHeader:forSection:] + 328
frame #4: 0x000000018b55f070 UIKit`__96-[UITableView _sectionHeaderView:withFrame:forSection:floating:reuseViewIfPossible:willDisplay:]_block_invoke + 332
frame #5: 0x000000018b0a71c4 UIKit`+[UIView(Animation) performWithoutAnimation:] + 104
frame #6: 0x000000018b376b68 UIKit`-[UITableView _sectionHeaderView:withFrame:forSection:floating:reuseViewIfPossible:willDisplay:] + 244
frame #7: 0x000000018b1c29dc UIKit`-[UITableView _updateVisibleHeadersAndFootersNow:] + 2484
frame #8: 0x000000018b1aeed8 UIKit`-[UITableView _updateVisibleCellsNow:isRecursive:] + 3236
frame #9: 0x000000018b1aa668 UIKit`-[UITableView layoutSubviews] + 140
frame #10: 0x000000018b0e7770 UIKit`-[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 1420
frame #11: 0x000000018568925c QuartzCore`-[CALayer layoutSublayers] + 184
frame #12: 0x000000018568d3ec QuartzCore`CA::Layer::layout_if_needed(CA::Transaction*) + 324
frame #13: 0x00000001855f9aa0 QuartzCore`CA::Context::commit_transaction(CA::Transaction*) + 320
frame #14: 0x00000001856215d0 QuartzCore`CA::Transaction::commit() + 580
frame #15: 0x0000000185622450 QuartzCore`CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, void*) + 92
frame #16: 0x00000001814ba910 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 32
frame #17: 0x00000001814b8238 CoreFoundation`__CFRunLoopDoObservers + 412
frame #18: 0x00000001814b8884 CoreFoundation`__CFRunLoopRun + 1436
frame #19: 0x00000001813d8da8 CoreFoundation`CFRunLoopRunSpecific + 552
frame #20: 0x00000001833bb020 GraphicsServices`GSEventRunModal + 100
frame #21: 0x000000018b3b978c UIKit`UIApplicationMain + 236
frame #22: 0x000000010410eb34 anchorplatform`main(argc=1, argv=0x000000016bcfb800) at main.m:14
frame #23: 0x0000000180e69fc0 libdyld.dylib`start + 4
因为 sectionHeader
是 UITableViewHeaderFooterView
类的私有属性,内部具体使用情况不详,使用 @property
声明后会自动生成该属性的 getter
和 setter
方法。
简单分析一下调用信息:
- 从线程信息看出该类内部调用了
setSectionHeader:
方法,知道是在对该对象赋值 - 接着进入了
objc_storeStrong
,说明在赋值时 实例变量被release
掉了 - 然后该属性调用了
objc_retain
, 这还是在set
方法内部的操作,但是做retain
操作时,该实例变量已经被release
掉了,触发崩溃
至于为什么有这种操作,还不太清楚。可能是 在该类内部,该属性使用完就释放掉?然后我重写了 setter
方法,导致在 retain
的时候,在对象已经被释放了,然后造成崩溃?
网友评论