Dealloc 時取 weak self 引起崩潰

2021-07-26 18:01:23 字數 2127 閱讀 9061

今天無意這中遇到乙個奇怪的崩潰,先上引起崩潰的**:

- (void)dealloc

當執行到dealloc的時候,程式就crash 掉了。

崩潰資訊如下:

to instance (0x160f6f890) of

class mfchatroomboardcontroller. it is possible that this object was over-released, or

isin

the process of deallocation.

(lldb)

error: empty command

(lldb) bt

* 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)

else

deallocating =

! (*allowsweakreference)(referent, sel_allowsweakreference);

}if (deallocating)

// now remember it and where it is being stored

weak_entry_t *entry;

if ((entry = weak_entry_for_referent(weak_table, referent)))

else

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)
這段**讓程式crash。

再看一下 _objc_fatal 這個函式

void _objc_fatal(const char *fmt, ...)

可以看到這個函式實際會在控制台輸出一段資訊,然後呼叫 _bojc_trap() 引起 crash. 而最後乙個函式呼叫剛好也對上我們之前的崩潰堆疊。

dealloc 的釋放順序

dealloc 的正確的書寫方式 void dealloc如下 的列印結果是 宣告 inte ce book nsobject end implementation book void dealloc end inte ce person nsobject property nonatomic,st...

AXIOS超時取消請求

今天發現專案在網路不好的時候發出請求會一直使頁面處於等待狀態,十分不友好。所以我在發出請求的函式中增加了取消axios請求的方法。設定如下 axios外 const canceltoken axios.canceltoken let cancel axios內 設定canceltoken 提前結束a...

iOS ARC環境下dealloc的使用

本文 至 眾所周知,ios開發的時候,使用arc的話,dealloc函式是不需要實現的,寫了反而會出錯。但有些特殊的情況,dealloc函式還是需要的。比如,在畫面關閉的時候,需要把viewcontroller的某些資源釋放,在viewdiddissppear不一定合適,viewdidunload一...