博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
如何使用__block 与 __weak
阅读量:5944 次
发布时间:2019-06-19

本文共 2451 字,大约阅读时间需要 8 分钟。

在使用block时要注意两点:

  1. block默认会拷贝局部变量的值,即所谓的闭包。
  2. block被某对象强引用,此时在block中使用这个对象,默认block会强引用这个对象。这时就产生了循环引用问题。

1. block默认会拷贝局部变量的值

(1)block默认会拷贝局部变量的值,block中的局部变量不可修改。

eg:代码1

//代码1- (void)testMethod {    int anInteger = 42;    void (^testBlock)(void) = ^{        NSLog(@"Integer is: %i", anInteger);    };        anInteger = 84;    testBlock();    //输出: Integer is: 42}复制代码

在block外声明局部变量并赋值, 在声明block时会copy局部变量当前的值(在此例中是anInteger的值始终是42)且不可修改。 此时block中的anIntegerblock外的anInteger不是同一个值(他两个的内存地址是不一样的)。所以就出现了上面的情况,anInteger = 84只是修改了block外的局部变量,它不会影响block里面的anInteger。同时block中的anInteger是不能被修改的。

(2)当某局部变量使用 __block 进行修饰时,此局部变量在block中不会产生copy。

eg: 代码2

//代码2	__block int anInteger = 42;	void (^testBlock)(void) = ^{	   NSLog(@"Integer is: %i", anInteger);	};	anInteger = 84;	testBlock();     	//输出:  Integer is: 84			//在block中也可以修改原来的值	__block int anInteger = 42;	void (^testBlock)(void) = ^{	   NSLog(@"Integer is: %i", anInteger);	   anInteger = 100;	};	testBlock();	NSLog(@"Value of original variable is now: %i", anInteger);		//输出:	Integer is: 42	Value of original variable is now: 100复制代码

(3)当局部变量是指针类型时,你可以在block中使用这个局部变量,并修改指针所指的对象的内容。

eg:代码3

//代码3	NSMutableArray *mArray = [NSMutableArray arrayWithObjects:@"a",@"b",@"abc",nil];	NSMutableArray *mArrayCount = [NSMutableArray arrayWithCapacity:1];		[mArray enumerateObjectsWithOptions:NSEnumerationConcurrent usingBlock: ^(id obj,NSUInteger idx, BOOL *stop){	    [mArrayCount addObject:[NSNumber numberWithInt:[obj length]]];	}];	    	NSLog(@"%@",mArrayCount);  //  1,1,3复制代码

代码3中与代码1的结论并不冲突。带代码3中 block中的mArrayCount确实是copy来的(与block外的mArrayCount在不同的内存空间,但是所指向的内存地址却是相同的。在block中改变的只是所指对象的内容。如果你在block中执行 mArrayCount=nil;,这才是修改局部变量的值。那么此时编译器会报错,因为违背了代码1.

2.使用__weak避免循环引用

如果一个对象强引用一个block, 然后在block中引用这个对象或者引用这个对象的属性, 此时block会强引用这个对象。 此时出现循环引用问题,造成内存泄露。__weak就是解决这个问题的。使用__weak 标记的引用是弱引用。此时在block中使用这个弱引用,block弱引用这个对象就不会产生循环引用的问题。 eg: 代码4

//代码4@property (nonatomic,copy)void (^block)(void);@property (nonatomic,copy)NSString *name;- (void)testMethod {    __weak typeof(self) weakSelf = self;    _block = ^{        weakSelf.name = @"hello world";  //此时不会产生循环引用问题        NSLog(weakSelf.name);    };    _block();}复制代码

此时有个问题没有解决.当在block 代码执行时self有可能会销毁成为nil, 如何解决确保block在执行时self不会被销毁那?那就使用代码5:

//代码5 __weak typeof(self) weakSelf = self; _block = ^{    __strong typeof(weakSelf) strongSelf = weakSelf; //就这一句,搞定   //这一句很重要,没有的话可能会崩溃的。   if(strongSelf==nil){
return;} strongSelf.name = @"hello world"; };复制代码

转载地址:http://bwzxx.baihongyu.com/

你可能感兴趣的文章
【记录】一些非常方便的命令集合
查看>>
#第六次会议#(4.21)
查看>>
phpQuery—基于jQuery的PHP实现
查看>>
StringUtils工具类的isBlank()方法使用说明
查看>>
FJ省队集训DAY3 T1
查看>>
FJ省队集训DAY5 T1
查看>>
错误解决记录------------mysql连接本地数据库显示"can't get hostname for your address"
查看>>
20155222 2016-2017-2 《Java程序设计》第10周学习总结
查看>>
5、Makefile基础知识汇总(转自陈皓总述)
查看>>
账号管理
查看>>
题解——洛谷 P2680 NOIP提高组 2015 运输计划
查看>>
A1043 Is It a Binary Search Tree (25 分)
查看>>
解决上传文件或图片时选择相同文件无法触发change事件的问题
查看>>
HTTP.sys 远程执行代码验证工具
查看>>
cout设置输出数据不显示科学计数法
查看>>
Windows 10下安装scrapy(pip方式,非wheel)
查看>>
递归犯过的错
查看>>
ModelForm理解简单运用(增删改查)
查看>>
MapReduce1.x与MapReduce2.x差异
查看>>
Spring AOP小记
查看>>