Objective-C Blocks

Block 相当于C或C++中的函数指针,相当于.NET或Java中的delegate

//Block声明

double (^blockName) (double, double) =

  ^ double (double firstParam, double secondParam){

    return firstParam * secondParam;

  }

 

//Block调用

double result = blockName(2,4);

 

block 会形成一个闭包

- (void) testMethod{

  int i = 42;

 

  void (^testBlock) (void) = ^{

   NSLog(@"%i", i); 

  };

 

  i = 84;

  testBlock();

}

这段代码中block i 的值42被testBlock capture了,即使在testBlock被调用之前修改i的值,testBlock的执行结果依然输出42. 而且在testBlock中即使修改 i 的值,也不会影响到原始的 i 的值。

 

可以使用 __block关键字,让在block外定义的变量能够被block内部的代码共享

__block int i = 42;

 

void (^testBlock) (void) = ^ {

  NSLog(@"%i", i);

  i = 100;

}

 

testBlock();

NSLog(@"%i", i);

这种情况下,输出结果为 42,100

 

block通常做为参数传递给方法,作为回调函数。block类型的参数一般放在方法参数列表的最后面

- (void) testMethod: (NSString *)str callback: (void(^) (void)) testBlock;

 

用typedef简化block语法

typedef void (^NothinBlock) (void);

这样就可以创建NothinBlock的实例,用来创建具有相同签名的block

NothinBlock callback = ^{

  ...

};

 

如果在一个class中定义一个block类型的属性,而这个block中capture了self的时候,可能会造成强引用循环

@interface Nothin : NSObject

@property (copy) void (^block) (void);

@end

 

@implementation Nothin

- (void) configureBlock{

  self.block = ^{

    [self doSomething];

  }

}

@end

 

因为self对block是强引用,而block中又capture了self,这个时候就造成强引用循环。为避免这种情况,需要在block中对self弱引用

- (void) configureBlock{

  Nothin * __weak weakSelf = self;

  self.block = ^{

    [weakSelf doSomething];

  }

}

这种情况下,当block执行完,对self的引用就解除了

 

posted @ 2014-07-29 11:53  Super猪  阅读(161)  评论(0编辑  收藏  举报