国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

Dealloc 時取 weak self 引起崩潰

2019-11-09 16:22:49
字體:
來源:轉載
供稿:網友

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

- (void)dealloc{ __weak __typeof(self)weak_self = self; NSLog(@"%@", weak_self);}

當執行到dealloc的時候,程序就crash 掉了。崩潰信息如下:

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. 而最后一個函數調用剛好也對上我們之前的崩潰堆棧。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 渑池县| 固镇县| 玉林市| 隆德县| 容城县| 古丈县| 喀喇| 辽中县| 蒙城县| 项城市| 佛山市| 双牌县| 乡城县| 富民县| 老河口市| 通山县| 奈曼旗| 博野县| 杭州市| 新沂市| 清徐县| 西藏| 福清市| 揭阳市| 和政县| 大连市| 阳泉市| 永年县| 江阴市| 西青区| 西城区| 元氏县| 黄石市| 上饶县| 上栗县| 黔南| 平遥县| 西平县| 乌海市| 鄂尔多斯市| 班玛县|