• Objective C 总结(八):Blocks


    块对象相当于C#中的匿名委托,是对一段代码的引用,@selector相当于C#中的委托,是对方法的引用。

    1. 创建块对象
          ^{
               NSLog(@"This is a block");
          }
    2. 声明块变量
        void (^simpleBlock)(void);
    3. 变量赋值
          simpleBlock = ^{
              NSLog(@"This is a block");
          };
    4. 一起写的语法
          void (^simpleBlock)(void) = ^{
              NSLog(@"This is a block");
          };
    5. 对块对象的调用
       simpleBlock();
    6. 带参数和返回值的块

          double (^multiplyTwoValues)(double, double) =
                                    ^(double firstValue, double secondValue) {
                                        return firstValue * secondValue;
                                    };
       
          double result = multiplyTwoValues(2,4);
       
          NSLog(@"The result is %f", result);
    7. 对作用域范围内变量的访问
      可以对块外定义的变量进行访问,块外的变量会传值给块,如要传递引用,需要对变量用__block进行修饰。
          int anInteger = 42;
       
          void (^testBlock)(void) = ^{
              NSLog(@"Integer is: %i", anInteger);
          };
       
          anInteger = 84;
       
          testBlock();

      上面代码输出

      Integer is: 42
          __block int anInteger = 42;
       
          void (^testBlock)(void) = ^{
              NSLog(@"Integer is: %i", anInteger);
          };
       
          anInteger = 84;
       
          testBlock();

      这段代码输出

      Integer is: 84

    块可以作为方法的参数进行传递

    方法的声明

    - (void)beginTaskWithCallbackBlock:(void (^)(void))callbackBlock;

    方法的实现

    - (void)beginTaskWithCallbackBlock:(void (^)(void))callbackBlock {
        ...
        callbackBlock();
    }

    注意:块只能作为方法的最后一个参数

    定义块类型

    typedef void (^XYZSimpleBlock)(void);
        XYZSimpleBlock anotherBlock = ^{
            ...
        };
    - (void)beginFetchWithCallbackBlock:(XYZSimpleBlock)callbackBlock {
        ...
        callbackBlock();
    }

    在复杂的使用是定义块类型很有用

    void (^(^complexBlock)(void (^)(void)))(void) = ^ (void (^aBlock)(void)) {
        ...
        return ^{
            ...
        };
    };
    XYZSimpleBlock (^betterBlock)(XYZSimpleBlock) = ^ (XYZSimpleBlock aBlock) {
        ...
        return ^{
            ...
        };
    };

    定义块类型的属性

    typedef void (^XYZSimpleBlock)(void);
     
    @interface XYZObject : NSObject
    @property (copy) XYZSimpleBlock blockProperty;
    @end

    当捕获自身时避免Strong引用循环

    @implementation XYZBlockKeeper
    - (void)configureBlock {
        self.block = ^{
            [self doSomething];    // capturing a strong reference to self
                                   // creates a strong reference cycle
        };
    }
    ...
    @end

    应修改成下面的代码

    - (void)configureBlock {
        XYZBlockKeeper * __weak weakSelf = self;
        self.block = ^{
            [weakSelf doSomething];   // capture the weak reference
                                      // to avoid the reference cycle
        }
    }

    块能遍历集合中的对象

    比如在NSArray中定义了枚举的方法

    - (void)enumerateObjectsUsingBlock:(void (^)(id obj, NSUInteger idx, BOOL *stop))block;
        [array enumerateObjectsUsingBlock:^ (id obj, NSUInteger idx, BOOL *stop) {
            if (...) {
                *stop = YES;
            }
        }];

    也可以并发执行

        [array enumerateObjectsWithOptions:NSEnumerationConcurrent
                                usingBlock:^ (id obj, NSUInteger idx, BOOL *stop) {
            ...
        }];

    NSDictionary也提供了类似的方法

        NSDictionary *dictionary = ...
        [dictionary enumerateKeysAndObjectsUsingBlock:^ (id key, id obj, BOOL *stop) {
            NSLog(@"key: %@, value: %@", key, obj);
        }];
  • 相关阅读:
    [0] RUP、FDD、SCRUM
    [0] Visual studio 2010 快捷键大全
    [0] Node.js
    Laravel开发:Laravel核心——服务容器的细节特性
    Laravel开发:Laravel核心——Ioc服务容器
    Composer的Autoload源码实现2——注册与运行
    Composer的Autoload源码实现1——启动与初始化
    PHP自动加载功能原理解析
    Lumen开发:phpunit单元测试
    php闭包简单实例
  • 原文地址:https://www.cnblogs.com/iprogrammer/p/3246245.html
Copyright © 2020-2023  润新知