一,块的基础知识
1.没有参数,也不返回值
void (^someBlock)()= ^{
//Block implementation here
}
2. 返回int值,并且接受俩个int做参数
int (^addBlock)(int a,int b) = ^(int a ,int b){
return a + b;
}
定义好之后,就可以像函数那样使用了,比方说,addBlock 块可以这样使用;
int add - addBlock (2, 5);//add = 7
块的强大之处是:在声明他得范围里,所有变量都可以为其所捕获,这页就是说,那个范围里的全部变量,在块里依然可用,比如,下面这段代码就定义的块,就使用了块以外的变量;
int additional = 5;
int ( ^addBlock) (int a,int b )= ^(int a,int b){
return a + b + additional ;
}
块中使用由于块里没有明确使用self变量,所以很容易就会忘记self变量其实也为块所捕获了,直接访问实例变量和通过self来访问是等效,所以一定要记住,self 也是个对象,因而块在捕获它时也会将其保留,如果self 所指代的那个对象同时也包留了块,那么这种情况通常就会导致"保留环",
二,为常用的块类型创建typedef
变量类型及相关赋值语句如下;
int (^variableName)(BOOL flag,int value) = ^(BOOL flag ,int value){
return someInt;
}
这个块的语法结构如下
return_type (^block_name)(parameters)
为乐隐藏复杂的块类型 我们可以用typedef 来给类型起个易读得名字
typedef int (^EOCSomeBlock) (bool ,flag ,int value)
这样就可以直接使用新的类型了
EocsomeBlock block = ^ (bool flag ,int value)
//例如
- (void )startWithCompletionHandler:(void (^)(NSData *data ,NSError *error))completion;
可以这样定义
typedef void (^EOCCompletionHandler) (NSData *data ,NSError *error);
- (void )startWithCompletionHandler:(EOCCompletionHandler)completion;
现在的参数看上去简单多了,而且易于理解;
1,以typedef 重新定义块类型,可令块变量用起来更加简单;
2.定义新类型时应遵守从现有得命名习惯,勿使其名称与别的类型相冲突.
3,不妨为同一个块标签定义多个类型的别名,
三 使用dispatch_once 来执行只需运行一次的线程安全代码
经常需要编写"只需要执行一次的线程安全代码"(thread - asfe single - code execution ).通过GCD所提供的dispatch_once 函数,很容易就能实现此功能;
标记应该声明在static 或global 作用域中,这样的话,在把只需要执行的一次的块传给dispatch_once 函数时,传进去得标记也是相同的