Objective-C语法之代码块(block)的使用

706 阅读5分钟

文章来源:blog.csdn.net/totogo2010/…

代码块本质上是和其他变量类似。不同的是,代码块存储的数据是一个函数体。使用代码块是,你可以像调用其他标准函数一样,传入参数数,并得到返回值。

脱字符(^)是块的语法标记。按照我们熟悉的参数语法规约所定义的返回值以及块的主体(也就是可以执行的代码)。下图是如何把块变量赋值给一个变量的语法讲解:\

\

按照调用函数的方式调用块对象变量就可以了:
int result = myBlock(4); // result是 28\

1、参数是NSString*的代码块

[cpp]  view plain copy

  1. void (^printBlock)(NSString *x);  
  2. printBlock = ^(NSString* str)  
  3. {  
  4.     NSLog(@"print:%@", str);  
  5. };  
  6. printBlock(@"hello world!");  

运行结果是: print:hello world!

2、代码用在字符串数组排序

[cpp]  view plain copy

  1. NSArray *stringArray = [NSArray arrayWithObjects:@"abc 1", @"abc 21", @"abc 12",@"abc 13",@"abc 05",nil];  
  2. NSComparator sortBlock = ^(id string1, id string2)  
  3. {  
  4.     return [string1 compare:string2];  
  5. };  
  6. NSArray *sortArray = [stringArray sortedArrayUsingComparator:sortBlock];  
  7. NSLog(@"sortArray:%@", sortArray);  

运行结果: sortArray:(

"abc 05",

"abc 1",

"abc 12",

"abc 13",

"abc 21"

)

3、代码块的递归调用

代码块想要递归调用,代码块变量必须是全局变量或者是静态变量,这样在程序启动的时候代码块变量就初始化了,可以递归调用

[cpp]  view plain copy

  1. static void (^ const blocks)(int) = ^(int i)  
  2. {  
  3.     if (i > 0) {  
  4.         NSLog(@"num:%d", i);  
  5.         blocks(i - 1);  
  6.     }  
  7. };  
  8. blocks(3);  

运行打印结果:

num:3

num:2

num:1

****4、在代码块中使用局部变量和全局变量

在代码块中可以使用和改变全局变量

[cpp]  view plain copy

  1. int global = 1000;  
  2. int main(int argc, const char * argv[])  
  3. {  
  4.     @autoreleasepool {  
  5.         void(^block)(void) = ^(void)  
  6.         {  
  7.             global++;  
  8.             NSLog(@"global:%d", global);  
  9.         };  
  10.         block();  
  11.         NSLog(@"global:%d", global);  
  12.     }  
  13.     return 0;  
  14. }  

运行打印结果:\

global:1001

global:1001

而局部变量可以使用,但是不能改变。

[cpp]  view plain copy

  1. int local = 500;  
  2. void(^block)(void) = ^(void)  
  3. {  
  4.       local++;  
  5.     NSLog(@"local:%d", local);  
  6. };  
  7. block();  
  8. NSLog(@"local:%d", local);  

在代码块中改变局部变量编译不通过。怎么在代码块中改变局部变量呢?在局部变量前面加上关键字:__block

[cpp]  view plain copy

  1. __block int local = 500;  
  2. void(^block)(void) = ^(void)  
  3. {  
  4.     local++;  
  5.     NSLog(@"local:%d", local);  
  6. };  
  7. block();  
  8. NSLog(@"local:%d", local);  

运行结果: local:501

local:501


著作权声明:本文由blog.csdn.net/totogo2010/原创,欢迎转载分享。请尊重作者劳动,转载时保留该声明和作者博客链接,谢谢!

\

学习block之前先用弄懂c语言的函数指针

看代码:

typedef int (^SumP)(int,int);//用typedef定义一个block类型

\

void test()

{

    printf("调用了test函数\n");

}

\

int sum(int a,int b)

{

   return a+b;

}

int main(int argc,constchar * argv[])

{

    void (*p)();//这是一个函数指针 能够指向一个返回值为void 没有形参的函数\

    //(*p)是固定写法,代表指针变量p将来肯定指向函数

    //左边的void:指针变量p指向的函数没有返回值

    //右边():指针变量p指向的函数没有形参

    p = test;//指针变量p指向test函数

    //利用指针变量间接调用取出函数

    (*p)();

    //也可以

    p();

    int(*xp)(int,int);//定义一个指向函数的指针返回值是int 函数的参数是int int

    xp =sum;

   int c = (*xp)(1,2);

    printf("c is %d\n",c);

\

    //下面来学习block

   /*

     作用:

     Block封装了一段代码,可以在任何时候执行

     Block可以作为函数参数或者函数的返回值,而本身又可以带输入参数或返回值

     block,在多线程、异步任务,集合遍历,集合排序、动画专场用得多

     */

    

    //block用来保存一段代码

    //block的标志 :^

    //block跟函数指针很像

    

    //定义block变量没有返回值没有参数

   void(^myblock)() = ^ {

        NSLog(@"---------");

        NSLog(@"---------");

    };

    //利用block变量调用block内部的代码

    myblock(); //运行block

    

    //定以一个block返回值为int函数的参数为int int

   int(^sumblock)(int ,int ) = ^(int a,int b){

       return a + b;

    };

    

   int sum = sumblock(10,11);

   NSLog(@"sum = %d",sum);

\

    //利用typedef定义block来创建一个block变量

   SumP sumblock1 = ^(int a,int b){

       return a - b;

    };

   int d = sumblock1(10,5);

    NSLog(@"d = %d",d);

\

    return 0;

}

\

作为方法或函数参数时,块可用作回调。被调用时,方法或函数执行部分工作,并在适当时刻,通过块回调正在调用的代码,以从中请求附加信息,或获取程序特定行为。块使调用方在调用时能够提供回调代码。块从相同的词法作用范围内采集数据(就像宿主方法或函数所做的那样),而非将所需数据打包在“关联”结构中。由于块代码无需在单独的方法或函数中实现,您的实施代码会更简单且更容易理解。

Objective-C 框架具有许多含块参数的方法。例如,Foundation 框架的 ​NSNotificationCenter ​类声明以下方法,该方法具有一个块参数:

| ```

  • (id)addObserverForName:(NSString *)name object:(id)obj queue:(NSOperationQueue *)queue usingBlock:(void (^)(NSNotification *note))block
| -------------------------------------------------------------------------------------------------------------------------------------------------- |

此方法将一个观察者添加到通知中心(通知在**采用设计模式使您的应用程序合理化**中有介绍)。指定名称的一则通知发布时,块被调用以处理该通知。

| ```
    opQ = [[NSOperationQueue alloc] init]; 
```                                               |
| ------------------------------------------------------------------------------------------------- |
| ```
    [[NSNotificationCenter defaultCenter] addObserverForName:@"CustomOperationCompleted" 
``` |
| ```
             object:nil queue:opQ 
```                                                        |
| ```
        usingBlock:^(NSNotification *notif) { 
```                                            |
| ```
        // handle the notification 
```                                                       |
| ```
    }];
```                                                                                   |

\