一、截获自动变量值
//截获自动变量值
int val = 132;
const char *fmt = "val = %d\n";
/*
在blocks中,block表达式使用的是在它声明之前的自动变量val。
block表达式截获所使用的自动变量的值,即保存了该自动变量的瞬间值,
因为block表达式保存了自动变量的值,所以在执行block语法后,即使改变bock中使用的自动变量的值也不会影响block执行时自动变量的值
所以两次输出的结果是一样的 都是:val = 132
*/
void (^blk)(void) = ^{
printf(fmt,val);
};
blk();
val = 12345;
blk();
二、__block 说明符
//__block说明符
/*
实际上,自动变量值截获只能保存在执行block语法瞬间的值,保存后就不能改写该值。
如果在block中尝试改变截获的自动变量的值,看看会有什么结果
*/
int val = 0;
void (^blk)(void) = ^{
val = 1;
};
blk();
这个时候就会出现如下图的错误提示啦:
那么该如何解决呢?-------- 使用 __block 说明符
//若想在block语法的表达式中将值赋给在block语法外声明的自动变量,
//需要在该自动变量的前面附加 __block 说明符,就可以实现在block内赋值。
__block int val = 0;
void (^blk)(void) = ^{
val = 1;
NSLog(@"val = %d",val);
};
blk();
三、截获的自动变量
上面提到,如果将值赋给block中的自动变量,就会产生编译错误。那么对于截获的objective-c对象,调用变更该对象的方法也会产生这样的编译错误吗?
请看下面的例子:
id array = [[NSMutableArray alloc]init];
void (^blk)() = ^{
id obj = [[NSObject alloc] init];
[array addObject:obj];
};
blk();
这个是没有问题的,首先,block中截获的是NSMutableArray类对象的结构体实例指针,这里是使用截获的值,所以没有问题,但是如果向截获的变量赋值则会产生编译错误。看看下面的例子:
id array = [[NSMutableArray alloc]init];
void (^blk)() = ^{
array = [[NSMutableArray alloc]init];
};
blk();
这个时候就会出现编译错误的提示啦!
显然,需要给截获的自动变量附加 __block 说明符才可以解决问题。
四、另外,在使用c语言数组的时候必须小心使用其指针,例如:
const char text[] = "hello world";
void (^blk)(void) = ^{
printf("%c \n",text[2]);
};
这个会出现如下的编译错误:
其实在block中,截获自动变量的方法并没有实现对c语言数组的截获,这时可以使用指针解决这个问题。
上面的代码稍微改动一下就可以了。
const char *text = "hello world";
void (^blk)(void) = ^{
printf("%c \n",text[2]);
};
blk();
运行时就可以输出 字符:l
五、
Block会保持一个strong指针指向block内被使用的所有对象,即这些被引用的对象会保持在heap中直到block生命周期结束。
MemoryCycle(内存循环)问题:
以下(在控制器类中)定义属性并使用Block 的代码:
@property(nonatomic ,strong) NSMutableArray *myBlocks;// block array
[self.myBlocksaddObject:^{ //Block可当作对象使用
[selfdoSomething];
}];
由于 Block 内引用了 self,因此self(通过myBlocks 属性) 和 Block 均有 一个strong 指针指向彼此,此时self 及 Block 均无法从内存中释放!
解决方法:
定义一个 weak 指针:
__weakMyClass *weakObj = self;
//arrayofblocks
@property(nonatomic,strong)NSArray*myBlocks;
[self.myBlocks addObject:^{
[weakObjdoSomething];
}];
Block拥有一个指向weakObj 的 weak 指针,self 拥有一个指向 myBlock 的 strong 指针。