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);
    }];

 

posted @ 2013-08-08 17:17  万有引用  阅读(243)  评论(0编辑  收藏  举报