1、关于__weak
__weak只能在ARC模式下使用,也只能修饰对象(比如NSString等),不能修饰基本数据类型(比如int等)
__weak修饰的对象在block中不可以被重新赋值。
__weak只在ARC下使用,可以避免循环引用。
__weak修饰对象不会增加引用

__weak __typeof(self) weakSelf = self;

self.testBlock = ^{

[weakSelf doSomeThing];

});

弱引用不会影响对象的释放,但是当对象被释放时,所有指向它的弱引用都会自定被置为 nil,这样可以防止野指针。

2、关于__block
__block不管是ARC还是MRC模式下都可以使用,可以修饰对象,还可以修饰基本数据类型。
在MRC下使用__block是可以避免循环引用的;
在ARC下使用 __block typeof(self)weakSelf = self;因为block是用过添加引用来访问实例变量的,所以self会被retain一次,block也是一个强引用,会引起循环引用。

__block修饰对象会增加引用

3、关于 __strong

- (void)viewDidLoad {

[super viewDidLoad];

MyOBJ *mm = [[MyOBJ alloc]init];

mm.name = @"Lilei";

__weak typeof(student) weakSelf = mm;

mm.doBlock = ^{

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

NSLog(@"my name is = %@",weakSelf.name);

});

};

mm.doBlock();

}

//输出:my name is = (null)

在dispatch_after这个函数里面。在doBlock()的block结束之后,mm被自动释放了。
又由于dispatch_after里面捕获的__weak的mm,在原对象释放之后,__weak对象就会变成nil,防止野指针。

那么我们怎么才能在weakSelf之后,block里面还能继续使用weakSelf之后的对象呢?

究其根本原因就是weakSelf之后,无法控制什么时候会被释放,为了保证在block内不会被释放,需要添加__strong。

在block里面使用的__strong修饰的weakSelf是为了在函数生命周期中防止self提前释放。strongSelf是一个自动变量当block执行完毕就会释放自动变量strongSelf不会对self进行一直进行强引用。

- (void)viewDidLoad {

[super viewDidLoad];

MyOBJ *mm = [[MyOBJ alloc]init];

mm.name = @"Hanmeimei";

__weak typeof(mm) weakSelf = mm;

mm.doBlock = ^{

__strong typeof(mm) strongSelf = weakSelf;

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

NSLog(@"my name is = %@",strongSelf.name);

});

};

mm.doBlock();

}

//输出:my name is = Hanmeimei

weakSelf 是为了block不持有self,避免Retain Circle循环引用。
在 Block 内如果需要访问 self 的方法、变量,建议使用 weakSelf。

strongSelf的目的是因为一旦进入block执行,假设不允许self在这个执行过程中释放,就需要加入strongSelf。block执行完后这个strongSelf 会自动释放,不会存在循环引用问题。
如果在 Block 内需要多次 访问 self,则需要使用 strongSelf。

4、关于 多层嵌套的block
4.1单层block

- (void)doSomething{

XXModel *model = [XXModel new];

__weak typeof(self) weakSelf = self;

model.dodoBlock = ^(NSString *title) {

__strong typeof(self) strongSelf = weakSelf;

strongSelf.titleLabel.text = title;

};

self.model = model;

}

- (void)viewDidLoad {

[super viewDidLoad];

[self doSomething];

}

4.2双层block

- (void)setUpModel{

XXModel *model = [XXModel new];

__weak typeof(self) weakSelf = self;

model.dodoBlock = ^(NSString *title) {

__strong typeof(self) strongSelf = weakSelf;//第一层

strongSelf.titleLabel.text = title;

__weak typeof(self) weakSelf2 = strongSelf;

strongSelf.model.dodoBlock = ^(NSString *title2) {

__strong typeof(self) strongSelf2 = weakSelf2;//第二层

strongSelf2.titleLabel.text = title2;

};

};

self.model = model;

}

这样就避免的引用循环,不管都多少个block嵌套,都可以按照这样来做。

转自:https://blog.csdn.net/nathan1987_/article/details/82749057

iOS开发-多层嵌套block中如何使用__weak和__strong的更多相关文章

  1. iOS开发实用技巧—Objective-C中的各种遍历(迭代)方式

    iOS开发实用技巧—Objective-C中的各种遍历(迭代)方式 说明: 1)该文简短介绍在iOS开发中遍历字典.数组和集合的几种常见方式. 2)该文对应的代码可以在下面的地址获得:https:// ...

  2. iOS开发:使用Block在两个界面之间传值(Block高级用法:Block传值)

    iOS开发:使用Block在两个界面之间传值(Block高级用法:Block传值)   使用Block的地方很多,其中传值只是其中的一小部分,下面介绍Block在两个界面之间的传值: 先说一下思想: ...

  3. iOS开发(OC)中的命名规范

    开小差:最近发现自己有一个经验主义的毛病,不太容易接受新的知识,这对从事技术研发的人来说不太合理,需要改之. 正文:通过读写大量代码我有自己的一套编程思路和习惯,自认为自己的编码习惯还是不错的,代码结 ...

  4. iOS开发拓展篇—xib中关于拖拽手势的潜在错误

    iOS开发拓展篇—xib中关于拖拽手势的潜在错误 一.错误说明 自定义一个用来封装工具条的类 搭建xib,并添加一个拖拽的手势. 主控制器的代码:加载工具条 封装工具条以及手势拖拽的监听事件 此时运行 ...

  5. iOS开发-Objective-C Block的实现方式

    前言:我们可以把Block当作一个闭包函数,它可以访问外部变量和局部变量,但默认是不可以修改外部变量.你可以使用它来做回调方法,比起使用代理(Delegate)会更加直观.顺带一提,苹果很多的接口(A ...

  6. C# Mongo DB 修改多层嵌套集合中的字段

    C# Mongo DB 修改嵌套集合中的字段 虽然c#的mongo 驱动很强大,而且还支持linq,但是一些复杂的操作语句还是比较困难 这里我用Bson实现功能 这是模型(我这里有多层嵌套) publ ...

  7. JsonPath:从多层嵌套Json中解析所需要的值

    问题 应用中,常常要从嵌套的JSON串中解析出所需要的数据.通常的做法是,先将JSON转换成Map, 然后一层层地判空和解析.可使用 JsonPath 来解决这个问题. 给定一个 JSON 串如下所示 ...

  8. iOS开发之集成iOS9中的Core Spotlight Framework搜索App的内容

    Spotlight在iOS9上做了一些新的改进, 也就是开放了一些新的API, 通过Core Spotlight Framework你可以在你的app中集成Spotlight.集成Spotlight的 ...

  9. iOS开发之使用block块进行数据遍历的方法

    看了一篇文章,发现遍历数组.字典中的数据时,除了使用for循环外,还可以使用block块进行操作,瞬间感觉iOS的语言代码确实有点高大上的感觉,下面就简单的介绍一下这个方法. 首先是最基本的运用形式, ...

随机推荐

  1. Jmeter4.0---- jmeter中写入java代码_简单了解(15)

    1.说明 BeanShell:是一个小型嵌入式Java源代码解释器,具有对象脚本语言特性,能够动态地执行标准JAVA语法,并利用在JavaScript和Perl中常见的的松散类型.命令.闭包等通用脚本 ...

  2. set-cookie中的SameSite属性

    原文:set-cookie中的SameSite属性 再见,CSRF:讲解set-cookie中的SameSite属性 2016-04-14 13:18:42 来源:360安全播报 作者:暗羽喵 阅读: ...

  3. ubuntu中安装字体雅黑和consolas

    Ubuntu的群体里偏向使用雅黑,我目前用的YaHei.Consolas 1.11 版本 (雅黑-Consolas的混合体) http://www.netmako.com/RobertLee/YaHe ...

  4. Django rest-framework框架-请求数据校验

    验证实例: class UserInfoSerializer(serializers.Serializer): title = serializer.CharField(error_messages= ...

  5. C#中DateTime.Ticks

    DateTime.Ticks:表示0001 年 1 月 1 日午夜 12:00:00 以来所经历的 100 纳秒数,即Ticks的属性为100纳秒(1Ticks = 0.0001毫秒). Unix时间 ...

  6. JS数组判断,方法

    怎么判断一个对象是不是数组? 首先可以用 ES5 提供的 isArray 方法进行判断(注意:Array.isArray是ES 5.1推出的,不支持IE6~8,所以在使用的时候也应注意兼容问题. ) ...

  7. LLVM的RTTI特性

    本文思路来源于http://llvm.org/docs/HowToSetUpLLVMStyleRTTI.html,叙述有不同,望谅解,希望能从其他方面帮助大家了解C++语言的底层实现. 背景 在LLV ...

  8. 2.第一个MyBatis程序

    1.导入jar包 2.定义实体类 3.创建对应的表 4.定义Dao接口 public interface StudentDAO { public void saveStudent(Student s) ...

  9. Delphi 定义线程对象

  10. ppp协议解析二

    转:http://blog.csdn.net/yangzheng_yz/article/details/11526747 PPP(Point to Point Protocol,点对点协议)协议是为在 ...