iOS block用法&注意点

看了好几篇和block有关的总结, 也打算来总结一下,让自己记得更清楚一些。

block是一种C language level的语法,其本质是一段代码,但是在objective c中,我们可以用指针把block当做参数,变量进行传递,也就是说这段代码,可以被当做一个参数,带入另一个函数中执行。

这会极大的方便许多之前编写麻烦的delegate method,因为可以续写代码意味着我们不需要再去conform protocol而只需要在初始化后面的跟着的completion block中写我们需要的代码。

先来看block的基本语法:

int (^testBlock)(int a, int b) = ^(int a, int b){
   return a + b;
}

定义一个叫testBlock的block,等号右边为实现。
不过在实际应用过程中,我经常用typedef定义一种类型的block,具体的代码实现则可以等到使用时按具体情况编写。使用如下:


//define a block type, takes boolean and returned object, void return
typedef void ^(CompletionBlock)(BOOL success, NSArray *objectsOrNil);

//use settingManger for example
@class  SettingManager

//insert the block in method  --- interface
- (void)update:(CompletionBlock)completionBlock;

//---implementation
- (void)update:(CompletionBlock)completionBlock{

   //previous upload
   if(update fail){
      completionBlock(NO, nil);
   }else{
      completionBlock(YES, returnedObjects);
   };

}


//use the above method in reality
[settingManager update:^(BOOL success, NSArray objectsOrNil){

     if(success){
    
     }else{

     };

}];


上面是一种常见的用法,completionBlock通常使用成功或失败两种情况,并且返回相关信息。由于不用像delegate method那样分开和update执行分开,block显得更加直观。

下面讨论一下block的作用域:
1. 当block定义在某函数内部时,allocation位于栈上,也就是说当函数执行结束,栈内内容会被释放,再使用这个block有可能会导致程序的崩溃.


  CompletionBlock blockTest; 

  {

    CompletionBlock blockTest = ^(BOOL success, NSArray ObjectsOrNil){
       NSLog("hello");
    }
  } 

blockTest(YES,nil);

2. block也可以在堆上,如果想要将其转移到堆上,应在定义时加上strong指针(ARC)情况下,这样block就可以有效的继续存在了!


__strong CompletionBlock blockTest;

  {

       blockTest = ^(BOOL success, NSArray ObjectsOrNil){
       NSLog("hello");
    }
  } 

blockTest(YES,nil);

3. block 不但可以修改传入的变量,也可以修改作用域内的任何变量, 但是必须在前面加上__block修饰符,不然会报错,另外。即使外部变量不会在block中被修改,我们也应该尽量加上__block字样,因为不加入修饰符会将该变量在block定义处之前的value存成常量供block使用,如果调用block的地方在函数最后,而block定义之后该变量经过了大量改变,那么我们想要的结果会与得到的结果南辕北辙。

这大致就是block比较重要的注意点。
给几个我觉得比较好的相关link:

http://www.cnblogs.com/biosli/archive/2013/05/29/iOS_Objective-C_Block.html
http://blog.csdn.net/yhawaii/article/details/7556739
http://yhawaii.github.io/ios/2013-12-20-iOS-Block.html

最近又偷懒了,老想着和室友打dota2,你个学渣!

Advertisements
This entry was posted in iOS and tagged . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s