一句话笔记,某段时间内遇到或看到的某个可记录的点。 2017-03-22
再遇 dzn_canDisplay 崩溃的错误
之前也有遇到这个错误 BUG, 当时打印的日志更加清晰一点,是线上的,大致知道是什么引发的,但是这次遇到这个 BUG, 直接是由 [UITableView layoutSubviews]
出来的,有点不一样...
第二反应的的解决办法, 直接解决了这个 BUG,但是一下子发现自己也不能娓娓道来。
- (void)dealloc {
_tableView.emptyDataSetSource = nil;
}
为什么说是第二反应呢?
PS:BUG 出现的流程,我从 HomeVC(TabBarVC)
==> ProductorVC
==> CartVC
==>CategoryVC(TabBarVC)
==> HomeVC(TabBarVC)
,然后崩了。
当时崩在这个地方,我的第一反应是
HomeVC
中出问题啦,后来发现 HomeVC
压根就没有使用 DZNEmptyDataSet ,所以第二反应应该是 CartVC
出的问题,然后想着 CartVC
都已经被释放掉了,为什么还会出现这个呢?那就是可能之前相关联的还没有清除干净,于是直接在 dealloc
中 进行 nil
处理。
另外也可以尝试更新库处理,EXC_BAD_ACCESS on dzn_canDisplay 中有人通过更新库解决了类似问题,所以目前相当于有两种方式,快速处理。
我暂时直接用的是 第一种,更新后发现有些变动了,改动自然多了一些。
- 1、在相应的
dealloc
中 进行 nil 处理。 - 2、更新 DZNEmptyDataSet 库
但是目前依然还有两个问题:
- 1、
CartVC
被释放了,为什么只在 点击HomeVC(TabBar)
中崩溃,点击其他TabBar
没有崩溃。 - 2、这种类似奔溃,到底是什么原因造成的,通常会哪些情况会遇到,怎样避免类似的问题出现?
PS: 这个 BUG 在 iOS 8 的时候,不会有问题,当我换到 iOS 10 之后的模拟器才有问题的。
1、
CartVC
被释放了,为什么只在 点击HomeVC(TabBar)
中崩溃,点击其他TabBar
没有崩溃。
我是这样理解的: 从操作流程来看,是从 HomeVC
进入的, 此时 HomeVC 是根视图控制器中,在这个控制器中,不断入栈,到最后 CartVC
返回 HomeVC
的时候属于最后的出栈,而这个最后的完成时间是要等回到 HomeVC
中 viewWillAppear
时才真正消失,然而此时它又调用了 CartVC
中的 self.tableView.emptyDataSetSource
所以崩溃了, 所以点击其他的TabBar
时相当于 还没有调用那个self
,所以没事。
暂时是这样理解的,感觉还不是很到位,后期想到再补充。
2、这种类似奔溃,到底是什么原因造成的 ?
2-1、dzn_canDisplay 处崩溃到底是怎么产生的?
说白了就是: self.emptyDataSetSource
已经被释放了, 还在使用到了。
突然想到了MRC 时代下,为什么会有类似代码出现了
- (void)dealloc {
self.delegate = nil;
}
因为 当时 用的是 assgin
, 所以还是很有可能 出现野指针的情况,所以 置 nil。
2-2、看看新版本的处理
首先新增加了一个 weak 处理的对象:
@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 最新版本的优化:
delegate Getter 方法 delegate Setter 方法objc_setAssociatedObject(self, kEmptyDataSetDelegate, delegate, OBJC_ASSOCIATION_ASSIGN);
objc_setAssociatedObject(self, kEmptyDataSetDelegate, [[DZNWeakObjectContainer alloc] initWithWeakObject:delegate], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
对比下,我们就发现其 delegate 的优化:
OBJC_ASSOCIATION_ASSIGN
== 》``OBJC_ASSOCIATION_RETAIN_NONATOMIC
;
delegate`` ==》
[[DZNWeakObjectContainer alloc] initWithWeakObject:delegate]
;
然后就避免了可能出现野指针的问题,从而不出现上面这个 BUG 啦。
同时反思下,怎样避免类似问题的呢?或者说发现这类问题的根源,个人感觉往往追究到底就内存这块的问题,这也让我想到了为什么面试时老喜欢 问内存的问题,想想这也是原因之一吧。
网友评论