BLOCK使用详解

在网上找到一篇block,比我之前写的详细,也更容易理解,所以复制下来收藏。 http://blog.csdn.net/victor_jiang1990/article/details/9623579

关于Block是什么这里就不介绍了, 可以自行搜索.

 本文参考文档:

《初识block》http://www.cocoachina.com/applenews/devnews/2013/0710/6569.html

《Blocks 编程要点》謝業蘭【老狼】翻译

1.声明一个Block

使用^操作符声明一个block变量和指示block文本的开始.Block本身的主体被{}包含,以;结束.

int (^myblock)(int);          

//第一个int表示返回值的类型,myBlock表示Block名,第二个int表示参数

          

2.实现Block

myblock = ^(int number){

        return number * 2;

    };

           Block可以简单的作为一个函数使用:

                     int result =myblock(3);   //result= 6

3.__block变量

Block内可以访问:局部变量, 传递的参数, 全局变量, 函数.还能访问定义在Block之外的,但在Block内部有它的作用域的非局部变量.

比如下面的非局部变量multiplier:

            intmultiplier =7;

              int(^myBlock)(int) = ^(int number) {

                   return number *multiplier;

    };

                     但是mutiplier是以const变量被拷贝并存储在Block中的,只可读,不可修改.

                    

以const拷贝的方式访问非局部变量

                               

以const拷贝的方式访问非局部变量,意味着block实际上并不是真正的访问了非局部变量—只不过在block中创建了非局部变量的一个flashshot,当定义block时,无论非局部变量的值是什么,都将被冻结,并且block会一直使用这个值,即使在之后修改了非局部变量的值.

                     intmultiplier = 7;

         int(^myBlock)(int) = ^(int number) {

              return number *multiplier;

         };

         int result = myblock(3);

      NSLog(@"result = %i", result); //result = 21

          multiplier= 8;

          result= myblock(3);

    NSLog(@"result = %i", result); //result = 21

           修改非局部变量

                      用__block存储修饰符来声明非局部变量:

                                __block intmultiplier = 7;

                     这将告诉block对非局部变量做引用处理,在block外部multiplier变量和内部的multiplier变量创建一个直接的链接.

通过引用的方式访问非局部变量

4.定义Block类型

           由于block数据类型的语法会把函数的声明搞得难以阅读,所以经常用typedef对block的签名做处理.

           typedef int(^MyBlock)(int);

           使用:

           MyBlock myBlock = ^(int number) {

        return number * 2;

    };

5.内存管理

           当block初始化的时候, 在栈中创建, 而栈空间会被重复使用,那么如果我们想在以后继续使用该block,就必须对block进行拷贝操作.

           在Objective-C中, block可以接收retain,release, copy消息.

6.Block作为参数使用

                     作为函数的参数

l  首先写一个函数

void fun(int arg1,int arg2, void(^myBlock2)(int a,int b))

{

    int num1 = arg1 + 1;

    int num2 = arg2 + 2;

    myBlock2(num1, num2);

}

l  调用函数

fun(10,20, ^(int a,int b) {

        self.resultLabel.text = [NSStringstringWithFormat:@"%i", a * b];

    });

                    

    该函数的作用是将两个参数处理后返回使用,实际中很多地方会用到.比如客户端与服务端交互,将客户端参数传给服务器,服务器处理后把有用的数据返回客户端使用.(这个就是回调机制了).

  

                     作为方法的参数

l  写一个方法

- (void)methodArg1:(int)arg1arg2:(int)arg2 block:(void(^)(int number))myBlock

{

    void(^currentBlock)(int num) = [myBlockcopy];

    currentBlock(arg1 + arg2);

    [currentBlock release];

}

l  调用方法

[self methodArg1:10 arg2:20 block:^(int number) {

        self.resultLabel.text = [NSStringstringWithFormat:@"%i", number];

    }];

                     注意上面Block作为参数的区别

                                函数: void(^myBlock2)(int a,int b)

                                方法: (void(^)(intnumber))myBlock

上面都有一个共同点就是当有多个参数的时候,Block都放在最后一个,这样的作用是代码清晰,方便阅读.(所以参数中最好不要有多个Block).

个人使用Block最多的地方是在回调机制中, 因为可以使用上下文中的数据, 实在很方便!

原文地址:https://www.cnblogs.com/AbelChen1991/p/3684077.html