一句話筆記,某段時(shí)間內(nèi)遇到或看到的某個(gè)可記錄的點(diǎn)。 2017-03-22
再遇 dzn_canDisplay 崩潰的錯(cuò)誤
之前也有遇到這個(gè)錯(cuò)誤 BUG祖能, 當(dāng)時(shí)打印的日志更加清晰一點(diǎn)赁项,是線上的,大致知道是什么引發(fā)的局齿,但是這次遇到這個(gè) BUG剧劝, 直接是由 [UITableView layoutSubviews]
出來的,有點(diǎn)不一樣...
第二反應(yīng)的的解決辦法抓歼, 直接解決了這個(gè) BUG讥此,但是一下子發(fā)現(xiàn)自己也不能娓娓道來。
- (void)dealloc {
_tableView.emptyDataSetSource = nil;
}
為什么說是第二反應(yīng)呢谣妻?
PS:BUG 出現(xiàn)的流程萄喳,我從 HomeVC(TabBarVC)
==> ProductorVC
==> CartVC
==>CategoryVC(TabBarVC)
==> HomeVC(TabBarVC)
,然后崩了蹋半。
當(dāng)時(shí)崩在這個(gè)地方他巨,我的第一反應(yīng)是
HomeVC
中出問題啦,后來發(fā)現(xiàn) HomeVC
壓根就沒有使用 DZNEmptyDataSet ,所以第二反應(yīng)應(yīng)該是 CartVC
出的問題染突,然后想著 CartVC
都已經(jīng)被釋放掉了捻爷,為什么還會(huì)出現(xiàn)這個(gè)呢?那就是可能之前相關(guān)聯(lián)的還沒有清除干凈份企,于是直接在 dealloc
中 進(jìn)行 nil
處理也榄。
另外也可以嘗試更新庫處理,EXC_BAD_ACCESS on dzn_canDisplay 中有人通過更新庫解決了類似問題司志,所以目前相當(dāng)于有兩種方式甜紫,快速處理。
我暫時(shí)直接用的是 第一種骂远,更新后發(fā)現(xiàn)有些變動(dòng)了囚霸,改動(dòng)自然多了一些。
- 1吧史、在相應(yīng)的
dealloc
中 進(jìn)行 nil 處理邮辽。 - 2、更新 DZNEmptyDataSet 庫
但是目前依然還有兩個(gè)問題:
- 1贸营、
CartVC
被釋放了吨述,為什么只在 點(diǎn)擊HomeVC(TabBar)
中崩潰,點(diǎn)擊其他TabBar
沒有崩潰钞脂。 - 2揣云、這種類似奔潰,到底是什么原因造成的冰啃,通常會(huì)哪些情況會(huì)遇到邓夕,怎樣避免類似的問題出現(xiàn)?
PS: 這個(gè) BUG 在 iOS 8 的時(shí)候阎毅,不會(huì)有問題焚刚,當(dāng)我換到 iOS 10 之后的模擬器才有問題的。
1扇调、
CartVC
被釋放了矿咕,為什么只在 點(diǎn)擊HomeVC(TabBar)
中崩潰,點(diǎn)擊其他TabBar
沒有崩潰狼钮。
我是這樣理解的: 從操作流程來看碳柱,是從 HomeVC
進(jìn)入的, 此時(shí) HomeVC 是根視圖控制器中熬芜,在這個(gè)控制器中莲镣,不斷入棧,到最后 CartVC
返回 HomeVC
的時(shí)候?qū)儆谧詈蟮某鰲O牙@個(gè)最后的完成時(shí)間是要等回到 HomeVC
中 viewWillAppear
時(shí)才真正消失瑞侮,然而此時(shí)它又調(diào)用了 CartVC
中的 self.tableView.emptyDataSetSource
所以崩潰了, 所以點(diǎn)擊其他的TabBar
時(shí)相當(dāng)于 還沒有調(diào)用那個(gè)self
的圆,所以沒事。
暫時(shí)是這樣理解的区岗,感覺還不是很到位略板,后期想到再補(bǔ)充毁枯。
2慈缔、這種類似奔潰,到底是什么原因造成的 种玛?
2-1藐鹤、dzn_canDisplay 處崩潰到底是怎么產(chǎn)生的?
說白了就是: self.emptyDataSetSource
已經(jīng)被釋放了赂韵, 還在使用到了娱节。
突然想到了MRC 時(shí)代下,為什么會(huì)有類似代碼出現(xiàn)了
- (void)dealloc {
self.delegate = nil;
}
因?yàn)?當(dāng)時(shí) 用的是 assgin
, 所以還是很有可能 出現(xiàn)野指針的情況祭示,所以 置 nil肄满。
2-2、看看新版本的處理
首先新增加了一個(gè) weak 處理的對(duì)象:
@interface DZNWeakObjectContainer : NSObject
@property (nonatomic, readonly, weak) id weakObject;
- (instancetype)initWithWeakObject:(id)object;
@end
@implementation DZNWeakObjectContainer
- (instancetype)initWithWeakObject:(id)object
{
self = [super init];
if (self) {
_weakObject = object;
}
return self;
}
DZNEmptyDataSet 最新版本的優(yōu)化:
objc_setAssociatedObject(self, kEmptyDataSetDelegate, delegate, OBJC_ASSOCIATION_ASSIGN);
objc_setAssociatedObject(self, kEmptyDataSetDelegate, [[DZNWeakObjectContainer alloc] initWithWeakObject:delegate], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
對(duì)比下质涛,我們就發(fā)現(xiàn)其 delegate 的優(yōu)化:
OBJC_ASSOCIATION_ASSIGN
== 》``OBJC_ASSOCIATION_RETAIN_NONATOMIC
;
delegate`` ==》
[[DZNWeakObjectContainer alloc] initWithWeakObject:delegate]
;
然后就避免了可能出現(xiàn)野指針的問題稠歉,從而不出現(xiàn)上面這個(gè) BUG 啦。
同時(shí)反思下汇陆,怎樣避免類似問題的呢怒炸?或者說發(fā)現(xiàn)這類問題的根源,個(gè)人感覺往往追究到底就內(nèi)存這塊的問題毡代,這也讓我想到了為什么面試時(shí)老喜歡 問內(nèi)存的問題阅羹,想想這也是原因之一吧。