dealloc时取weakself引起崩溃
生活随笔
收集整理的這篇文章主要介紹了
dealloc时取weakself引起崩溃
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
今天無意這中遇到一個奇怪的崩潰,先上引起崩潰的代碼:
- (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.
說明不允許在 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 viablebool 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 storedweak_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(); }可以看到這個函數實際會在控制臺輸出一段信息,然后調用 _objc_trap() 引起 crash. 而最后一個函數調用剛好也對上我們之前的崩潰堆棧。
轉自:http://www.jianshu.com/p/841f60876180
轉載于:https://www.cnblogs.com/huangzs/p/7455404.html
總結
以上是生活随笔為你收集整理的dealloc时取weakself引起崩溃的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: web.xml上下文配置
- 下一篇: iOS网络编程实践--NSStream实