iOS循环引用

iOS循环引用

  • 当前类的闭包/Block属性,用到了当前类,就会造成循环引用
    1. 此闭包/Block应该是当前类的属性,我们经常对Block进行copy,copy到堆中,以便后用。
    2. 单方向引用是不会产生循环引用。需要self引用闭包/Block,Block中使用self。
  • 有两个规则:
    1. 如果你是通过引用来访问一个实例变量,那么将强引用至self。
    2. 如果你是通过值来访问一个实例变量,那么将直接强引用至这个“值”变量。

Object-C Block循环引用情况

  • 一般来说我们总会在设置Block之后,在合适的时间回调Block,而不希望回调Block的时候Block已经被释放了,所以我们需要对Block进行copy,copy到堆中,以便后用。
  • 当一个Block被Copy的时候,如果你在Block里进行了一些调用,那么将会有一个强引用指向这些调用方法的调用者。

swift 中闭包循环引用情况

class ViewController: UIViewController {
    // 1.闭包是当前类属性
    var allCallBack :(()->())?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        CyclicLead {
            // 闭包引用当前类
            print(self.view)
        }
    }

    // 循环引用的方法
    func CyclicLead(completionBack:@escaping ()->()) -> Void {
        // 2.当前类引用闭包
        allCallBack = completionBack
        
        DispatchQueue.global().async {
            
            DispatchQueue.main.async {
                completionBack()
            }
        }
    }
    
    // 当对象销毁时会调用
    deinit {
        print("销毁了")
    }
}

解除循环引用

OC方式

  • 方式一
__weak typeof(self) weakSelf = self;
self.block = ^(NSString *name){
    NSLog(@"view:%@", weakSelf.view);
};
  • 方式二
__unsafe_unretained typeof (self) weakSelf = self;
[self loadData:^{
    NSLog(@"%@", weakSelf.view);
}];

swift方式

  • 方案一:
    • 使用weak,对当前控制器使用弱引用
    // 解决方案一:
    /*
    细节1:var ,weak 只能修饰var,不能修饰 let
     'weak' must be a mutable variable,
      because it may change at runtime
      weak 可能会被在运行时被修改 -> 指向的对象一旦被释放,会被自动设置为nil
    细节2: weakSelf?  weakSelf!   两种解包方式
    ?可选解包 - 如果self已经被释放,不会向对象发送getter消息
        可选解包只是单纯的发送消息,没有计算
    ! 强行解包 - 如果self已经被释放,强行解包会导致崩溃
        强行解包可以参与计算,可选项不能直接参与到计算
    */
    weak var weakSelf = self
    CyclicLead {
        print(weakSelf?.view)
    }
  • 方案二:
    • 和方案一类型,只是书写方式更加简单
    • 可以写在闭包中,并且在闭包中用到的self都是弱引用
CyclicLead {[weak self]()->() in            
    print(self?.view)
}
// 缩减写法
CyclicLead {[weak self] in
    print(self?.view)
}
  • 方案三:
    • 使用关键字unowned
    • 从行为上来说 unowned 更像OC中的 unsafe_unretained
    • unowned 表示:即使它原来引用的对象被释放了,仍然会保持对被已经释放了的对象的一个 "无效的" 引用,它不能是 Optional 值,也不会被指向 nil
    • [unowned self]表示 {} 中的所有 self 都是 assign 的,不会强引用,但是,如果对象释放,指针地址不会变化如果对象被释放,继续调用,就会出现野指针的问题
CyclicLead {[unowned self]()->() in
    print(self?.view)
}

// 缩减写法
CyclicLead {[unowned self] in
    print(self?.view)
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏腾讯高校合作

【倒计时7天】2018教育部-腾讯公司产学合作协同育人项目申请即将截止!

15720
来自专栏前端桃园

知识体系解决迷茫的你

最近在星球里群里都有小伙伴说道自己对未来的路比较迷茫,一旦闲下来就不知道自己改干啥,今天我这篇文章就是让你觉得一天给你 25 个小时你都不够用,觉得睡觉都是浪费...

21640
来自专栏Ken的杂谈

【系统设置】CentOS 修改机器名

18130
来自专栏腾讯社交用户体验设计

ISUX Xcube智能一键生成H5

51220
来自专栏钱塘大数据

理工男图解零维到十维空间,烧脑已过度,受不了啦!

让我们从一个点开始,和我们几何意义上的点一样,它没有大小、没有维度。它只是被想象出来的、作为标志一个位置的点。它什么也没有,空间、时间通通不存在,这就是零维度。

33530
来自专栏钱塘大数据

中国互联网协会发布:《2018中国互联网发展报告》

在2018中国互联网大会闭幕论坛上,中国互联网协会正式发布《中国互联网发展报告2018》(以下简称《报告》)。《中国互联网发展报告》是由中国互联网协会与中国互联...

13650
来自专栏怀英的自我修炼

考研英语-1-导学

英二图表作文要重视。总体而言,英语一会比英语二难点。不过就写作而言,英语二会比英语一有难度,毕竟图表作文并不好写。

11910
来自专栏FSociety

SQL中GROUP BY用法示例

GROUP BY我们可以先从字面上来理解,GROUP表示分组,BY后面写字段名,就表示根据哪个字段进行分组,如果有用Excel比较多的话,GROUP BY比较类...

5.2K20
来自专栏微信公众号:小白课代表

不只是软件,在线也可以免费下载百度文库了。

不管是学生,还是职场员工,下载各种文档几乎是不可避免的,各种XXX.docx,XXX.pptx更是家常便饭,人们最常用的就是百度文库,豆丁文库,道客巴巴这些下载...

44630
来自专栏haifeiWu与他朋友们的专栏

复杂业务下向Mysql导入30万条数据代码优化的踩坑记录

从毕业到现在第一次接触到超过30万条数据导入MySQL的场景(有点low),就是在顺丰公司接入我司EMM产品时需要将AD中的员工数据导入MySQL中,因此楼主负...

29740

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励