BLOCK使用详解
在网上找到一篇block,比我之前写的详细,也更容易理解,所以复制下来收藏。 http://blog.csdn.net/victor_jiang1990/article/details/9623579
关于Block是什么这里就不介绍了, 可以自行搜索.
本文参考文档:
《初识block》http://www.cocoachina.com/applenews/devnews/2013/0710/6569.html
《Blocks 编程要点》謝業蘭【老狼】翻译
1.声明一个Block
使用^操作符声明一个block变量和指示block文本的开始.Block本身的主体被{}包含,以;结束.
int (^myblock)(int);
//第一个int表示返回值的类型,myBlock表示Block名,第二个int表示参数
2.实现Block
myblock = ^(int number){
return number * 2;
};
Block可以简单的作为一个函数使用:
int result =myblock(3); //result= 6
3.__block变量
Block内可以访问:局部变量, 传递的参数, 全局变量, 函数.还能访问定义在Block之外的,但在Block内部有它的作用域的非局部变量.
比如下面的非局部变量multiplier:
intmultiplier =7;
int(^myBlock)(int) = ^(int number) {
return number *multiplier;
};
但是mutiplier是以const变量被拷贝并存储在Block中的,只可读,不可修改.
以const拷贝的方式访问非局部变量
以const拷贝的方式访问非局部变量,意味着block实际上并不是真正的访问了非局部变量—只不过在block中创建了非局部变量的一个flashshot,当定义block时,无论非局部变量的值是什么,都将被冻结,并且block会一直使用这个值,即使在之后修改了非局部变量的值.
intmultiplier = 7;
int(^myBlock)(int) = ^(int number) {
return number *multiplier;
};
int result = myblock(3);
NSLog(@"result = %i", result); //result = 21
multiplier= 8;
result= myblock(3);
NSLog(@"result = %i", result); //result = 21
修改非局部变量
用__block存储修饰符来声明非局部变量:
__block intmultiplier = 7;
这将告诉block对非局部变量做引用处理,在block外部multiplier变量和内部的multiplier变量创建一个直接的链接.
通过引用的方式访问非局部变量
4.定义Block类型
由于block数据类型的语法会把函数的声明搞得难以阅读,所以经常用typedef对block的签名做处理.
typedef int(^MyBlock)(int);
使用:
MyBlock myBlock = ^(int number) {
return number * 2;
};
5.内存管理
当block初始化的时候, 在栈中创建, 而栈空间会被重复使用,那么如果我们想在以后继续使用该block,就必须对block进行拷贝操作.
在Objective-C中, block可以接收retain,release, copy消息.
6.Block作为参数使用
作为函数的参数
l 首先写一个函数
void fun(int arg1,int arg2, void(^myBlock2)(int a,int b))
{
int num1 = arg1 + 1;
int num2 = arg2 + 2;
myBlock2(num1, num2);
}
l 调用函数
fun(10,20, ^(int a,int b) {
self.resultLabel.text = [NSStringstringWithFormat:@"%i", a * b];
});
该函数的作用是将两个参数处理后返回使用,实际中很多地方会用到.比如客户端与服务端交互,将客户端参数传给服务器,服务器处理后把有用的数据返回客户端使用.(这个就是回调机制了).
作为方法的参数
l 写一个方法
- (void)methodArg1:(int)arg1arg2:(int)arg2 block:(void(^)(int number))myBlock
{
void(^currentBlock)(int num) = [myBlockcopy];
currentBlock(arg1 + arg2);
[currentBlock release];
}
l 调用方法
[self methodArg1:10 arg2:20 block:^(int number) {
self.resultLabel.text = [NSStringstringWithFormat:@"%i", number];
}];
注意上面Block作为参数的区别
函数: void(^myBlock2)(int a,int b)
方法: (void(^)(intnumber))myBlock
上面都有一个共同点就是当有多个参数的时候,Block都放在最后一个,这样的作用是代码清晰,方便阅读.(所以参数中最好不要有多个Block).
个人使用Block最多的地方是在回调机制中, 因为可以使用上下文中的数据, 实在很方便!