Objective C Block

SoccerZZM 2014-06-12

       Apple在C, Objective-C,C++加上Block這個延申用法。目前只有Mac 10.6 和iOS 4有支援。Block是由一堆可执行的程式组成,也可以称做沒有名字的Function (Anonymous function)。如果是Mac 10.6 或 iOS 4.0 之前的平台可以利用 http://code.google.com/p/plblocks/ 这個project得以支援Block语法。

   Apple有一个叫做GCD(Grand Central Dispach)的新功能,用在同步处理(concurrency)的环境下有更好的效率,是苹果为多核多线程编程出现的解决方案。Block语法产生的动机就是來自于GCD,用Block包好一个工作量交给GCD,GCD有一个宏观的视野可以来分配CPU,GPU,Memory。

    Block的实际行为和Function很像,最大的差别是在可以存取同一个Scope的变量值。Block实体形式如下:

       ^(传入参数列){行为主体};

     Block实体开头是“^”,接着是由小括号所包起来的参数列(比如 int a, int b, int c),行为主体由大括号包起来,专有名字叫做block literal。行为主体可以用return回传值,类型会被compiler自动辨别。如果没有参数列要写成: ^(void)。

       简单例子:

      

^(int a){return a*a;};
  
int result = ^(int a){return a*a;}(5);
    NSLog(@"%d", result);
    上面的方法往往太复杂,很多时候我们使用一个Block Pointer的东西来简化用法。

    

    Block Pointer是这样定义的:

     回传值(^名字)(参数列);

       

//声明一个square的Block Pointer,其所指向的Block有一个int输入和int输出
    int (^square)(int);
    //将Block实体指定给square
    square = ^(int a){ return a*a ; };
    //调用方法,感觉是是不是很像function的用法?
    int result = square(5);
    NSLog(@"%d", result);
   
void myFunction(int (^mySquare)(int));     //function的定义,将Block作为参数
    int (^mySquare)(int) = ^(int a){return a*a;};   //定义一个mySquare的Block pointer变量
    myFunction(mySquare);    //把mySquare作为myFunction的参数
     Block需要注意的知识点

 1、可以读取和Block pointer同一个Scope的变量值:

{
        int outA = 8;
        int (^myPtr)(int) = ^(int a){ return outA + a;};
        //block里面可以读取同一类型的outA的值
        int result = myPtr(3);  // result is 11
        NSLog(@"result=%d", result);
    }
 2.Block块体里用的scope定义的变量

    对于基本类型,这里copy的值是变量的值,不会变。如果它是一个记忆体的位置(地址),换句话说,就是这个变量是个指针的话,它的值是可以在block里被改变的。

 3.读取static变量的值

{
        static int outA = 8;
        int (^myPtr)(int) = ^(int a){return outA + a;};
        outA = 5;
        int result = myPtr(3);  //result的值是8,因为outA是static类型的变量
        NSLog(@"result=%d", result);
        
    }

  4、Block Variable类型的变量

   在某个变量前面如果加上修饰字“__block”的话(注意,block前面有两个下划线),这个变量就称作block variable。

  那么在block里面就可以任意修改此变量的值,如下代码:

    

{
        __block int num = 5;
        
        int (^myPtr)(int) = ^(int a){return num++;};
        int (^myPtr2)(int) = ^(int a){return num++;};
        int result = myPtr(0);   //result的值为5,num的值为6
        result = myPtr2(0);      //result的值为6,num的值为7
        NSLog(@"result=%d", result);  
    
    }

   

   可以通过通过typedef定义一个区块

  

typedef void (^SVHTTPRequestCompletionHandler)(id response, NSHTTPURLResponse *urlResponse, NSError *error);

    可以执行区块

    if(block){

       block(response,urlResponse,error);

    }

相关推荐