文档章节

iOS 解决闭环引用问题

IamOkay
 IamOkay
发布于 2016/03/26 10:29
字数 843
阅读 587
收藏 7
什么是闭环引用:

所谓闭环引用是2个货2个以上的相互关联的类的对象互相引用,造成了一种引用闭环问题,这种引用造成的问题是闭环内的所有对象都无法及时销毁,这种问题不是Objective-C和Swift所特有的,在常见的语言如Python,C/C++中均存在。

注:国内大多数程序员称为“循环引用”,单这种称呼很不恰当,闭环未必会循环,循环同样未必会闭环,只有闭环才是导致引用释放问题的关键,而不是循环

这里的闭环可以认为是一种死循环。


什么情况下容易出现闭环引用

使用代理和blocks时容易出现闭环引用


如下,Page应该用了Book,Book引用了Page

OC中出现这种问题会导致dealloc不会被调用,在OC中解决此类问题,需要解除循环引用

我们可以手动让我们引用的对象变量赋值为nil(在合适的位置)

self.studentDelegate = nil;

当然,上面的代码需要【天时,地利,人和】,因此不适合一般性程序。


解决上面的问题有如下步骤
  1. 需要让Blocks变成弱引用(__weak或者__block)

  2. 让代理(委托)弱拷贝(weak)

来段网上的代码

文/邻家菇凉(简书作者)
原文链接:http://www.jianshu.com/p/48b3d47fac12
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

主要代码如下

#import "NetworkTools.h"
@interface NetworkTools ()
//用一个属性 来记录 函数传递过来的 block
@property (nonatomic, copy) void(^finishedBlock)(NSString *);
@end

@implementation NetworkTools
- (void)loadData:(void (^)(NSString *))finishedCallBack {    
//开始记录blcok
    self.finishedBlock = finishedCallBack;    
    dispatch_async(dispatch_get_global_queue(0, 0), ^{

        [NSThread sleepForTimeInterval:3];        
        //开始耗时任务
        NSLog(@"开始加载数据");       
         dispatch_async(dispatch_get_main_queue(), ^{            
         //调用方法
            [self working];
        });
    }); 
}

- (void) working {    //执行block
    if (self.finishedBlock) {        
    self.finishedBlock(@"<html>");
    }
}

- (void)dealloc {    
    NSLog(@"Tools dealloc");
}
@end

实现引用

#import "ViewController.h"
#import "NetworkTools.h"
@interface ViewController ()

////解决方案切入点一,使用weak,防止 ViewController引用NetWorkTools成为强引用
@property (nonatomic, weak) NetworkTools *tools;

@end@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];    
    self.tools = [[NetworkTools alloc] init];
    [self injectBlocksForNetWorkTools];
}
//解决方案切入点二,使用 __weak
- (void) injectBlocksForNetWorkTools{
     __weak typeof(self) weakSelf = self;
    [self.tools loadData:^(NSString *html) {
        __strong typeof(self) strongSelf = weakSelf;        
        NSLog(@"%@%@",html,strongSelf.view);
        strongSelf.view.backgroundColor = [UIColor redColor];
    }];
}

- (void)dealloc {    
     NSLog(@"VC dealloc");
}
@end


在这里说明一下__block和__weak的区别

因此,__block和__weak修饰符的区别其实是挺明显的: 
1.__block不管是ARC还是MRC模式下都可以使用,可以修饰对象,还可以修饰基本数据类型。 
2.__weak只能在ARC模式下使用,也只能修饰对象(NSString),不能修饰基本数据类型(int)。 
3.__block对象可以在block中被重新赋值,__weak不可以。 


在这里总结一下具体方案
  1. 代理一定要使用弱引用

  2. Blocks可以使用__weak或者__block可防止强引用

  3. __block保证原有变量不被修改,__block对象在block中是可以被修改、重新赋值的,__weak容易释放,不能保证局部性,没有常量特征

  4. __block对象在block中不会被block强引用一次,从而不会出现闭环引用问题。

  5. Blocks属性尽量使用weak修饰

  6. 只要保证引用闭环的其中一段弱引用就可以避免引用闭环


© 著作权归作者所有

IamOkay

IamOkay

粉丝 204
博文 483
码字总数 403228
作品 0
海淀
程序员
私信 提问
iOS与JS交互之UIWebView-JavaScriptCore框架

级别:★★☆☆☆ 标签:「iOS与JS交互」「UIWebView与JS交互」「JavaScriptCore」 作者: Xs·H 审校: QiShare团队 先解释下标题:“iOS与JS交互”。iOS指原生代码(文章只有示例),JS指前...

QiShare
2018/08/30
0
0
iOS与JS交互之UIWebView-JSExport协议

级别:★★☆☆☆ 标签:「iOS与JS交互」「UIWebView与JS交互」「JSExport」 作者: Xs·H 审校: QiShare团队 先解释下标题:“iOS与JS交互”。iOS指原生代码(文章只有示例),JS指前端(不...

QiShare
2018/08/31
0
0
2018 iOS 面试题大全(补充完整版)

原文地址:2018 iOS 面试题大全 由于原作者并没有继续更新,这里我转过来继续更新下 这个栏目将持续更新--请iOS的小伙伴关注! 1、iOS 应用导航模式有哪些? 2、iOS 中持久化方式有哪些? 3、...

Theendisthebegi
2018/11/15
0
0
iOS与JS交互之WKWebView-WKScriptMessageHandler协议

级别:★★☆☆☆ 标签:「iOS与JS交互」「WKWebView与JS交互」「WKJSMessageHandler」 作者: Xs·H 审校: QiShare团队 先解释下标题:“iOS与JS交互”。iOS指原生代码(文章只有示例),J...

QiShare
2018/09/02
0
0
面试官自述:面向高级开发人员的iOS面试问题

当您准备进行技术性iOS面试时,了解您可能会询问哪些主题以及经验丰富的iOS开发人员期望什么是非常重要的。 这是许多硅谷公司用来衡量iOS候选人资历水平的一系列问题。 这些问题涉及iOS开发的...

菇哒微课
2018/04/26
0
0

没有更多内容

加载失败,请刷新页面

加载更多

一次看懂 Https 证书认证

TLS > 传输层安全性协定 TLS(Transport Layer Security),及其前身安全套接层 SSL(Secure Sockets Layer)是一种安全协议,目的是为网际网路通信,提供安全及数据完整性保障。 如图,TLS...

极客收藏夹
33分钟前
4
0
https证书买哪家好?有哪些供应商

在选购https证书前除了要了解类型外,还需要了解https证书供应商,毕竟不同的供应商,提供的产品质量与服务也是有差异的。今天小编就为大家讲讲https证书供应商方面的内容,希望各位会喜欢。...

安信证书
35分钟前
5
0
Zuul 配置

概述:zuul底层是基于servlet,是由一系列的filter链构成。 1、路由配置 a、单例serverId映射 zuul: routes: client-a: path: /client/** serviceId: client-a 意思是...

java框架开发者
53分钟前
3
0
zk中FinalRequestProcessor解析

是处理器最后一个环节 FinalRequestProcessor implements RequestProcessor 处理器链最后一个环节处理事务和非事务请求最后一个环节 构造器 public FinalRequestProcessor(ZooKeeperServer z...

writeademo
53分钟前
3
0
Axios 详解

首先祝广大程序猿们节日快乐! 一、axios简介 基于promise,用于浏览器和node.js的http客户端 二、特点 支持浏览器和 node.js 支持 promise 能拦截请求和响应 能转换请求和响应数据 能取消请求...

张兴华ZHero
54分钟前
8
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部