Dealloc 时取 weak self 时崩溃
来源:互联网 发布:unity3d户型模型 编辑:程序博客网 时间:2024/04/30 06:44
今天无意这中遇到一个奇怪的崩溃,先上引起崩溃的代码:
- (void)dealloc{ __weak __typeof(self)weak_self = self; NSLog(@"%@", weak_self);}
当执行到dealloc的时候,程序就crash 掉了。
崩溃信息如下:
objc[4572]: Cannot form weak reference to instance (0x160f6f890) of class MFChatRoomBoardController. It is possible that this object was over-released, or is in the process of deallocation.(lldb) error: empty command(lldb) bt* thread #1: tid = 0x35914d, 0x0000000182307aac libobjc.A.dylib`_objc_trap(), queue = 'com.apple.main-thread', stop reason = EXC_BREAKPOINT (code=1, subcode=0x182307aac) * frame #0: 0x0000000182307aac libobjc.A.dylib`_objc_trap() frame #1: 0x0000000182307b24 libobjc.A.dylib`_objc_fatal(char const*, ...) + 88 frame #2: 0x0000000182319890 libobjc.A.dylib`weak_register_no_lock + 316 frame #3: 0x0000000182320688 libobjc.A.dylib`objc_initWeak + 224 frame #4: 0x000000010022bf8c MakeFriends`-[MFChatRoomBoardController dealloc](self=0x0000000160f6f890, _cmd="dealloc") + 36 at MFChatRoomBoardController.m:31
其中,可以在控制台明确看到这样一段描述:
objc[4572]: Cannot form weak reference to instance (0x160f6f890) of class MFChatRoomBoardController. It is possible that this object was over-released, or is in the process of deallocation.
说明不允许在 dealloc 的时候取 weak self.
查看了一下 weak_register_no_lock
的函数代码,找到问题所在。
id weak_register_no_lock(weak_table_t *weak_table, id referent_id, id *referrer_id){ objc_object *referent = (objc_object *)referent_id; objc_object **referrer = (objc_object **)referrer_id; if (!referent || referent->isTaggedPointer()) return referent_id; // ensure that the referenced object is viable bool deallocating; if (!referent->ISA()->hasCustomRR()) { deallocating = referent->rootIsDeallocating(); } else { BOOL (*allowsWeakReference)(objc_object *, SEL) = (BOOL(*)(objc_object *, SEL)) object_getMethodImplementation((id)referent, SEL_allowsWeakReference); if ((IMP)allowsWeakReference == _objc_msgForward) { return nil; } deallocating = ! (*allowsWeakReference)(referent, SEL_allowsWeakReference); } if (deallocating) { _objc_fatal("Cannot form weak reference to instance (%p) of " "class %s. It is possible that this object was " "over-released, or is in the process of deallocation.", (void*)referent, object_getClassName((id)referent)); } // now remember it and where it is being stored weak_entry_t *entry; if ((entry = weak_entry_for_referent(weak_table, referent))) { append_referrer(entry, referrer); } else { weak_entry_t new_entry; new_entry.referent = referent; new_entry.out_of_line = 0; new_entry.inline_referrers[0] = referrer; for (size_t i = 1; i < WEAK_INLINE_COUNT; i++) { new_entry.inline_referrers[i] = nil; } weak_grow_maybe(weak_table); weak_entry_insert(weak_table, &new_entry); } // Do not set *referrer. objc_storeWeak() requires that the // value not change. return referent_id;}
可以看出,runtime 是通过检查引用计数的个数来判断对象是否在 deallocting, 然后通过
if (deallocating) { _objc_fatal("Cannot form weak reference to instance (%p) of " "class %s. It is possible that this object was " "over-released, or is in the process of deallocation.", (void*)referent, object_getClassName((id)referent)); }
这段代码让程序crash。
再看一下 _objc_fatal 这个函数
void _objc_fatal(const char *fmt, ...){ va_list ap; char *buf1; char *buf2; va_start(ap,fmt); vasprintf(&buf1, fmt, ap); va_end (ap); asprintf(&buf2, "objc[%d]: %s\n", getpid(), buf1); _objc_syslog(buf2); _objc_crashlog(buf2); _objc_trap();}
可以看到这个函数实际会在控制台输出一段信息,然后调用 _bojc_trap() 引起 crash. 而最后一个函数调用刚好也对上我们之前的崩溃堆栈。
0 0
- Dealloc 时取 weak self 时崩溃
- Dealloc 时取 weak self 引起崩溃
- - (void)dealloc { __weak __typeof(self)weak_self = self; NSLog(@"%@", weak_self); }代码崩溃问题
- iOS weak & strong self
- weak & strong self
- weak & strong self
- block weak self strongself
- swift 中使用weak self
- 定义一个weak的self
- unowned self, 和 weak delegate
- iOS WKWebview的dealloc方法崩溃问题
- MMDrawerController 切换页面时不调用dealloc
- weak 属性需要在dealloc中置为nil吗
- Block中weak/strong self的用法
- 崩溃,写在崩溃濒临时!!~
- 【转】self.myOutlet=nil、viewDidUnload、dealloc的本质剖析
- dealloc
- dealloc
- Java 线程池的原理与实现
- 63. Unique Paths II
- 顺序表(Seqlist)&链表(List)的基础操作
- OCR字符切割实例
- Matlab预分配内存优化for循环
- Dealloc 时取 weak self 时崩溃
- 详解spring中每个jar包的作用
- 在Android开发中如何避免内存泄露
- java 实现n个整数的全排列
- 3、struts2_拦截器
- SpringMVC数据绑定全面示例(复杂对象,数组等)
- Python 学习点滴
- 基于IBM Bluemix的数据缓存应用实例
- 找出UILabel引起异常的文字