swift中循环引用的处理 weak与unowned

2018年2月26日更新

最近在项目用到了 weak | unowned 又有些思考.
大部分情况推荐使用weak

举个栗子
var bossView: BossView?

// 比较好的处理方式
bossView = BossView()
bossView.tmpView.selectBlock = { [weak bossView] _ in
    bossView?.tmpView.name = "Tony"
}
// 或者
bossView = BossView()
bossView.tmpView.selectBlock = { [weak bossView] _ in
    guard let weakView = bossView else { return }
    weakView.tmpView.name = "Tony"
}

// 有一定的崩溃可能
//  bossView = BossView()
tmpView.selectBlock = { [unowned bossView] _ in
     bossView.tmpView.name = "Tony"
    // bossView为属性等情况,   如果bossView为nil 则崩溃.
}

历史纪录:

1. Objective-C中的block避免循环引用的方法

 __weak typeof(self) weakSelf = self;
self.block = ^{ 
     __strong typeof(self) strongSelf = weakSelf;
    [strongSelf doSomething];
 };

2. Swift使用weak避免循环引用

一般使用weak的处理不是很优雅可能如下:

self.closure = { [weak self] in 
    self?.doSomeThing()
}

使用 self?. 如果闭包中判断比较多,数据处理复杂难免会有使用 ! 强解包的情况, 所以很不优雅也有一定风险.
故而可以用 guard 处理一下

self.closure = { [weak self] in 
    guard let weakSelf = self { return }
    // 之后正常使用weakSelf代替self
    weakSelf.doSomeThing()
}

不过按照官方文档的推荐使用unowned应该更为合理.

3. Swift中使用unowned避免循环引用

// 请拼了老命保证self不是nil.
// 换句话说自己引用自己可以用unowned,自己引用其他人, 都不值得信任. 请weak
self.closure = { [unowned self] in
    self.doSomething()
}

2017.7.18. by xiaozao

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容