----------简介
-------什么是block
Block是一个C级别的语法以及运行时的一个特性,和标准C中的函数(函数指针)类似,但是其运行需要编译器和运行时支持,从ios4.0开始就很好的支持Block,Block是C级别的语法和运行时特性。Block比较类似C函数,但是Block比之C函数,其灵活性体现在栈内存、堆内存的引用,我们甚至可以将一个Block作为参数传给其他的函数或者Block。
Block除了能够定义参数列表、返回类型外,还能够获取被定义时的词法范围内的状态(比如局部变量),并且在一定条件下(比如使用__block变量)能够修改这些状态。此外,这些可修改的状态在相同词法范围内的多个block之间是共享的,即便出了该词法范围(比如栈展开,出了作用域),仍可以继续共享或者修改这些状态。通常来说,block都是一些简短代码片段的封装,适用作工作单元,通常用来做并发任务、遍历、以及回调。
先来简单的写个block
void (^temp)(int,int)= ^(int num1,int num2)
{
NSLog(@"%d",num1-num2);
};
temp(2,1);
输出结果 : 1
我们可以看出可以重外部传值进去的,我们不止可以传整型值,字符型,float 等都可以
__blockint piece =0;
int (^price)(int)= ^(int num)
{
piece =10;
return piece*num;
};
NSLog(@"%d",price(1));
输出结果:10
也可以提前定义好block
typedefvoid(^sum) (int a,int b);
sum littleSum = ^(int a,int b)
{
NSLog(@"%d",a+b);
};
littleSum (1,2);
输出结果:3
由此可以看出block其实很简单,
Block object特点
Block object 可以有返回值,可以接受参数。BlockObjects可以内敛定义,或者当做一个独立的代码块来看待。内敛创建是与block object作为一个独立的代码块来执行时相比,能够访问block object的变量范围完全不同。
自定义独立的block语句块类型作为OC参数传递到方法中
声明intToStringConverter是一个参数是一个NSInteger型的变量,返回值是NSString *,的block语句块,^:标示block吧
typedefNSString * (^intToStringConverter) (NSInteger value);
具体的与上面声明的相同类型的block语句块实现----当然上面类型的你可以具体实现好多种
NSString * (^intToString)(NSInteger) = ^(NSInteger value) {
return [NSString stringWithFormat:@"%d", value];
};
调用方式:NSString * str = intToString(1000);
- (NSString *)convertIntToString:(NSInteger)value withBlockObject:(intToStringConverter)blockObject
{
return blockObject(value);
}
自定义内敛的block语句块类型作为OC参数传递到方法中---内敛就是写到函数内部
typedef NSString * (^intToStringConverter) (NSInteger value);
如果声明block类型之后,没有与声明类型对应的block具体语句块,可以写内敛的block块
部分内敛
- (void)doTheConversion
{
intToStringConverter inlineBlock = ^(NSInteger value) {
return [NSStringstringWithFormat:@"%d", value];
};
NSString * result = [selfconvertIntToString:10001withBlockObject:inlineBlock];
NSLog(@"%@", result);
}
完全内敛--这种用法官方方法中很常见,但是,很多都是无参无返回值的,如下
dispatch_async(globalQueue, ^{
});
- (void)doTheConversion2
{
NSString * result = [selfconvertIntToString:10101withBlockObject:^NSString *(NSInteger value) {
NSString * inResult = [NSStringstringWithFormat:@"%d", value];
return inResult;
}];
NSLog(@"%@", result);
}
独立与内敛block object变量访问权限
独立
局部变量 : 可读可写
self : 只能当成参数传进去,作为参数的self可以像正常的self一样使用,但是,要调用的方法必须在这个独立的block object语句块的前面。
点语法声明的变量 :只能用setter getter方法访问
内敛
局部变量 : 可读可写(block{}内部的)
外面的局部变量:加__block可读可写,否则只能读且保存了这个变量的一个只读复制值(与该block在同一方法内部的局部变量)
self : 可以直接使用,
原话 : 在内联block object获取self和那些创建内联block object的词法范围内定义的self完全一样。
点语法声明的变量 : 可以使用点语法,也可以使用setter getter方法访问
要点:block object在其词法区域内会为局部变量(外局部)复制值,只读复制值。加__block增加可读功能,且block不再复制变量的值,这一点很重要,比如使用ASIHttpRequest的时候,如果用block方式发送请求,则必须
__block ASIHTTPRequest*request =[ASIHTTPRequest requestWithURL:url];这样写才可以,告诉block不要保存请求,防止保留循环。
接下来在写个我们一般常用的block页面回调(反向传值)
在你要push的页面.h里面写定义
typedefvoid(^sBlock) (NSString *);
@property(nonatomic,strong)sBlock blocks;
然后去.m里面去给它赋值或者说你要传回去的值
if (self.blocks) {
self.blocks(@"hello word");
}
这时 你就可以在前一个页面取到你传回去的值了。
tow.blocks = ^(NSString *str){
NSLog(@"%@",str);
};
好了 这就是我个人理解的block 大家不喜忽喷。也请各位大神给我指点下我的不对之处。谢谢 (*^__^*)