关于Block的一些详细的介绍相信网上的资料非常充分和详细了。不过Block作为iOS里面也算是相当“怪异”的一种存在,所以开一贴从初学到深入地讲解Block,你会发现Block非常灵活强大!
首先来看看Block标准的语法:
语法格式上偏离OC的易读而贴近C的语法。感觉更像一个拥有返回值和参数列表的操作“块”。即函数指针。
接下来看看几种不同的使用:
1.直接地内联使用:
NSDictionary* dic = [NSDictionary dictionary];
dic = @{@"key1":@"values1", @"key2":@"values2", @"key3":@"values3"};
/** inline Block **/
[dic enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL* stop){
NSLog(@"@value for key : %@ is %@", key, value);
}];
- (void)enumerateKeysAndObjectsUsingBlock:(void (^)(KeyType key, ObjectType obj, BOOL *stop))block NS_AVAILABLE(10_6, 4_0);
而如果作为参数声明的话,是写语法的前半部分 (返回值)(^ block 标志)(参数列表) ,而在调用使用的时候写的是后半部分 ^ block标志 (参数列表) { block 操作 };
同理,用UIView的静态动画方法时候:
[UIView animateWithDuration:1
delay:2
options:UIViewAnimationOptionBeginFromCurrentState
animations:^{
imageView.frame =CGRectMake(80, 100, 160, 160);
}
completion:nil];
+ (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^ __nullable)(BOOL finished))completion NS_AVAILABLE_IOS(4_0);
后面的两个block分别是没有返回值和参数的纯操作block。
这也是我们最常用的block使用,在AFNextworking这些非常有名的三方库大量的例子。后续会继续慢慢学习到。
2.使用 NSOperation 的子类 NSBlockOperation 来操作block : (比较小众)
NSBlockOperation* op = [[NSBlockOperation alloc] init];
[op addExecutionBlock:^{
NSLog(@"Block operation here. ");
}];
因为现成的接口没有直接执行该block操作,调用的时候就会比较复杂一点:
3.直接声明,直接使用:
void(^printXAndY)(int , int) = ^(int x, int y){
printf("%d %d\n", x, y);
};
printXAndY(123, 456);
4.用typedef 声明 作为变量使用, 这个是最灵活最强大的!
用typedef 声明三种具有代表性的block:
typedef void (^BoolBlock)(BOOL); //一个只接受一个BOOL参数,没有返回值的block, BOOL参数名称可以省略
typedef int (^IntBlock)(void); //一个没有参数,返回int的block
typedef BoolBlock (^HugBlock) (IntBlock); //参数和返回值都是block的block,从这里可以看出block更像一种类型
定义个一个属性:
@property (nonatomic, strong)BoolBlock testBoolBlock;
使用:
BOOL yyes = YES;
self.testBoolBlock = ^(BOOL testValue){
NSLog(@"testValue is : %@", testValue?@"YES":@"NO");
};
self.testBoolBlock(yyes);
相信非常好理解,是不是很灵活啊!! 这样非常能体现出 block 作为变量的属性,用属性来声明的话,整体类的调用会便捷很多。
其他两个也同理使用,只不过是将普通类型换乘block 或者其他类型罢了。
一个例子:
甚至能更简洁,省略掉调用的时候的空参数:
这两段代码效果完全一样。嘿是不是很炫酷呢, 所以呢,不能完全将block当成一个变量,因为没有变量不声明直接使用的(除了常量)。
另外一个例子:
众所周知,NSArray只可以添加对象,而block就是如此奇异的一种存在,连数组都可以直接添加之。
参考 :
Reference - 1 : 51的教程,非常棒! : http://mobile.51cto.com/hot-403897.htm
Reference - 2 : 总结得很好 ! : http://my.oschina.net/leejan97/blog/268536
Reference - 3 : 深入难度了解 : http://blog.csdn.net/fengsh998/article/details/38090205
Reference - 4 : 总结一流 : http://blog.csdn.net/smking/article/details/8424902
Reference - 5 : cocoa : http://www.cocoachina.com/ios/20150109/10891.html
Reference - 6 : 唐巧的文章 ,很多很多的东西别人都是从唐巧那里取得出来的 :
http://blog.devtang.com/blog/2013/07/28/a-look-inside-blocks/