zoukankan      html  css  js  c++  java
  • 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最多的地方是在回调机制中, 因为可以使用上下文中的数据, 实在很方便!

  • 相关阅读:
    对soc-audio体系snd_soc_machine和snd_soc_dai_link简单理解
    I2S
    alsa和oss声音系统比较
    break 和 continue
    phalcon查询:单条查询,多条查询,多表查询
    phalcon: 独立的映射,字段名名别名
    phpexcel: 数据导出
    php:Mcrypt响应慢的原因解决备注
    js:s上次预览,上传图片预览,图片上传预览
    yii2: 点击编辑后,左侧的连接(a.navtab)失效,变成在新窗口打开
  • 原文地址:https://www.cnblogs.com/AbelChen1991/p/3684077.html
Copyright © 2011-2022 走看看