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)
}

iOS循环引用的更多相关文章

  1. iOS 循环引用解决方案

    一.BLOCK 循环引用 一般表现为,某个类将block作为自己的属性变量,然后该类在block的方法体里面又使用了该类本身.构成循环引用. // 定义 block 的时候,会对外部变量做一次 cop ...

  2. iOS 循环引用

    1.循环引用一般是指:A持有B,B同时持有A,从而导致死循环无法释放对象. 2.一般循环引用出现在block和delegate中,而一般解决方法就是将self变成weakSelf(强引用变成弱引用), ...

  3. iOS循环引用问题

    今天面试问道了循环引用,所以就看了看,原来只是知道使用了Block容易造成循环引用.今天就来简单的介绍一些循环引用. 先来简单介绍一下什么是循环引用? 循环引用可以简单的理解成:A对象引用了B对象,B ...

  4. iOS 循环引用讲解(中)

    谈到循环引用,可能是delegate为啥非得用weak修饰,可能是block为啥要被特殊对待,你也可能仅仅想到了一个weakSelf,因为它能解决99%的关于循环引用的事情.下面我以个人的理解谈谈循环 ...

  5. iOS循环引用常见场景和解决办法

    好多场景会导致循环引用,例如使用Block.线程.委托.通知.观察者都可能会导致循环引用. 1.委托 遵守一个规则,委托方持有代理方的强引用,代理方持有委托方的弱引用. 实际场景中,委托方会是一个控制 ...

  6. iOS 循环引用 委托 (实例说明)

    如何避免循环引用造成的内存泄漏呢: 以delegate模式为例(viewcontroller和view之间就是代理模式,viewcontroller有view的使用权,viewcontroller同时 ...

  7. iOS之weak和strong、懒加载及循环引用

    一.weak和strong 1.理解 刚开始学UI的时候,对于weak和strong的描述看得最多的就是“由ARC引入,weak相当于OC中的assign,但是weak用于修饰对象,但是他们都不会造成 ...

  8. 【转】iOS学习之容易造成循环引用的三种场景

    ARC已经出来很久了,自动释放内存的确很方便,但是并非绝对安全绝对不会产生内存泄露.导致iOS对象无法按预期释放的一个无形杀手是——循环引用.循环引用可以简单理解为A引用了B,而B又引用了A,双方都同 ...

  9. 【原】iOS容易造成循环引用的三种场景,就在你我身边!

    ARC已经出来很久了,自动释放内存的确很方便,但是并非绝对安全绝对不会产生内存泄露.导致iOS对象无法按预期释放的一个无形杀手是——循环引用.循环引用可以简单理解为A引用了B,而B又引用了A,双方都同 ...

随机推荐

  1. js实现replaceAll功能

    js中没有原生的replaceAll 方法. function replaceAll(str , replaceKey , replaceVal){ var reg = new RegExp(repl ...

  2. 2016/3/27 PHP中include和require的区别详解

    1.概要 require()语句的性能与include()相类似,都是包括并运行指定文件.不同之处在于:对include()语句来说,在执行文件时每次都要进行读取和评估:而对于require()来说, ...

  3. ou've likely run out of ephemeral ports on your system

    redis.exceptions.ConnectionError: Error 99 connecting to 127.0.0.1:6379. Cannot assign requested add ...

  4. cocos2dx笔记1:概述

    1.核心的类和功能 CCDirector gameLoop,实现场景绘制.多个场景之间切换控制.控制游戏的停止,暂停,等生命周期. CCScene 场景类,每一个场景能够理解为一个游戏镜头.状态 CC ...

  5. RK3288-OTA编译失败解决办法【转】

    本文转载自:http://blog.csdn.net/wangxueming/article/details/52448630 在执行make  otapackage的时候出现该错误,是由于drmsi ...

  6. HDU3642 Get The Treasury —— 求矩形交体积 线段树 + 扫描线 + 离散化

    题目链接:https://vjudge.net/problem/HDU-3642 Jack knows that there is a great underground treasury in a ...

  7. 运算符:三目运算符,运算符优先级,sizeof,自增自减,取余

    一://---------运算符-----------// 1.运算符是告诉编译程序执行特定算术或逻辑操作的符号. 2.按照功能划分: 算术运算符. 关系运算符与逻辑运算符.按位运算符. 3.运算符根 ...

  8. BZOJ_2081_[Poi2010]Beads_哈希

    BZOJ_2081_[Poi2010]Beads_哈希 Description Zxl有一次决定制造一条项链,她以非常便宜的价格买了一长条鲜艳的珊瑚珠子,她现在也有一个机器,能把这条珠子切成很多块(子 ...

  9. BZOJ4561: [JLoi2016]圆的异或并 计算几何+treap

    因为本题保证两圆之间只有相包含或相离(不用担心两圆重合 因为我没有RE) 所以每个圆之间的相对位置是确定的  也就是可以按极角排序的, 所以可以按横坐标排序后 扫描同时用treap维护加圆删圆(即遇到 ...

  10. 【转】浏览器中输入url后发生了什么

    原文地址:http://www.jianshu.com/p/c1dfc6caa520 在学习前端的过程中经常看到这样一个问题:当你在浏览器中输入url后发生了什么?下面是个人学习过程中的总结,供个人复 ...