zoukankan      html  css  js  c++  java
  • Block的使用--初探Block

    看了两天的Block。

    网上是有非常多解说与教程,也有讲得非常好的。这里就主要解说下我的理解与收获。欢迎拍砖。


    所谓block。我觉得应该是一个闭包函数。而闭包,就是说block以及内部全部的变量生命周期都在其调用函数的生命周期内。

    它一被调用完毕,则会被立刻释放。这里不讲运行机制,仅仅简要地讲基本的用法(这里所讲是基于ARC的环境下)。

    定义以及使用

    1、放在函数体内的Block:生命周期:仅仅存在于函数体。与函数体内的局部变量相似。

    其定义方式跟函数还是非常相似的。为了简便理解我们对照下block与函数的定义。先看一下最简单的形式,无返回值带參。先看Block直接放在函数体内的形式: 
    

    函数:

    - (void)printBlock:(NSString *)output {
        NSLog(@"output == %@", output);
    }

    Block直接放在函数体内的形式:

    void(^printBlock)(NSString *) = ^(NSString *output)
    {
        NSLog(@"output == %@", output);
    };

    这里能够看到。我们的函数体一般形式是:

    - (返回值) 函数名: (形參)...

    调用形式是:[调用对象 函数名(形參)];

    那我们放在函数体内的Block定义则是:

    返回值 (^ Block名)( 形參 ) = ^( 形參 ){ //实现内容 }; 

    调用形式是 :Block名(形參)。

    这里的Block就相当于是一个内嵌函数。

    声明与实现要同一时候放在一起。形式就非常像我们寻常使用的对象赋值一样:id obj = ... ;

    2、放在函数外的Block。

    即为类内部范围内的全局Block。生命周期为整个类内部。

    定义与用法都与上面一致,仅仅只是就像局部变量与类变量一样是否可被其它方法调用而已。为了更简单明了我们能够看一下这个代码:
    
        //普通方法定义
        - (void)printBlock:(NSString *)output {
            NSLog(@"output == %@", output);
        }
    
        //函数体外的Block
        void(^printBlock)(NSString *) = ^(NSString *output)
        {
          NSLog(@"output == %@", output);
        };
    
        //Block调用
        - (void)printSomething {
           printBlock(@"I'm printBlock");
        }

    3、放在类定义头文件的Block。

    可被实例对象拥有。生命周期为整个实例对象。

    头文件里的定义(1):

    typedef void(^printBlockClass)(NSString *);
    
    @interface BlockClass : NSObject
    @property (nonatomic, copy)printBlockClass print;
    @end
    
    //或者在实现文件里:
    //但这样的实如今内部的Block我也不知道有什么卵用。实际应用不大。
    @interface BlockClass : NSObject
    {
        printBlockClass print;
    }
    @end

    头文件里的定义(2):

    //与方式一的差别无非像是自己定义一种结构然后你再去使用一样
    @interface BlockClass : NSObject
    @property (nonatomic, copy) void(^printBlockClass)(NSSting *output);
    @end
    这样的把Block作为属性的情况是比較多用于页面传值中。

    关于Block的使用另一下几个注意点: 1、仅仅有在调用Block的时候才会运行{}内部的代码(就比方把Block定义在函数体内不调用是不会运行的)。

    2、在Block的{}内部代码中是对外部的变量能够引用,但不能改变。假设试图更改会产生一个编译器错误。除非你把想要更改的变量声明时加上 __block关键字。 3、在block使用过程要注意不要产生循环引用。

    关于循环引用(Memory Recycle)这里有一篇文章写得不错。有兴趣能够看看:http://blog.csdn.net/fengsh998/article/details/38090205

  • 相关阅读:
    托管和使用WCF服务:WAS(Windows激活服务)
    突发的灵感
    C# 常见图像处理效果
    C# WinForm TreeView 递归选择父节点和子节点
    C# WinForm ComboBox 枚举 选定值
    C# Socket 异步 UDP
    C# WinForm 判断窗体控件是否修改过
    C# 线程同步 信号量 Semaphore
    C# WinForm ComboBox Items 选定值
    C# WinForm ComboBox 自定义数据项 (ComboBoxItem )
  • 原文地址:https://www.cnblogs.com/yutingliuyl/p/7070940.html
Copyright © 2011-2022 走看看