参考自:http://www.devdiv.com/iOS_iPhone-iOS_5_Programming_Cookbook%E7%BF%BB%E8%AF%91_%E7%AC%AC%E4%BA%94%E7%AB%A0_%E5%B9%B6%E5%8F%91-thread-127260-1-1.html
Block Objects 有时被称作闭包。构建 Block Objects 和构建传统的 C 函数类似。Block Objects 可以有返回值,可以接受参数。BlockObjects 可以内敛定义,或者当做一个独立的代码块来看待,这一点与 C 函数相同。当内联创建时与 Block Object 作为一个独立代码块来执行时相比,能够访问Block Object 的变量范围完全不同。
block的几种适用场合:
任务完成时回调
处理消息监听回调处理
错误回调处理
枚举回调
视图动画、变换
排序
独立Block Objects:
void (^independentBlockObject)(void) = ^(void){
NSInteger localInteger = 10;
NSLog(@"local integer = %ld",(long)localInteger);
localInteger = 20;
NSLog(@"local integer = %ld",(long)localInteger);
};
对于独立Block Objects,实现 Object 的 Objective-C 方法的局部变量只能从中读取,
不能写入。
内联Block Object:
//内联Block
- (void)simpleMethod
{
NSUInteger outsideVariable = 10;
NSMutableArray *array = [[NSMutableArray alloc]
initWithObjects:@"obj1", @"obj2", nil];
[array sortUsingComparator:^NSComparisonResult(id obj1, id obj2){
NSInteger insideVariable = 20;
NSLog(@"Outside variable = %lu", (unsigned long)outsideVariable); //在这个Block里不能使outsideVariable的值变化,如果要改变outsideVariable,可以在定义outsideVariable时加上__block存储类的前缀
NSLog(@"Inside variable = %lu", (unsigned long)insideVariable);
NSLog(@"self = %@", self);
return NSOrderedSame;
}];
}
对于内联 Block Objects,那些在 BlockObject 执行过程中定义的局部变量是可读写
的,换句话说,对于 Block Objects 自身的局部变量来说,Block Objects 有个读写存
取。
对于内联 Block Objects,实现 Object 的 Objective-C 方法的局部变量只能从中读取,
不能写入。不过还有一个例外,如果定义它们通过 __block 存储类型定义的话,
Block Object 可以写入此类的变量。
只有当你使用声明属性的 setter and getter 方法你才能获取独立 Block Objects 内部的
NSObject 的这些属性;在一个独立 Block Object 使用 Dot Notation 方法你无法获取一个Object 的声明属性。
代码示例:
我们类中有一个 NSString 的类已声明属性叫做 stringProperty:
|
#import "GCDAppDelegate.h" @implementation GCDAppDelegate @synthesize stringProperty;
- (void) simpleMethod{
NSMutableArray *array = [[NSMutableArray alloc] initWithObjects:@"obj1",
@"obj2", nil];
[array sortUsingComparator:^NSComparisonResult(id obj1, id obj2) {
NSLog(@"self = %@", self);
self.stringProperty = @"Block Objects"; NSLog(@"String property = %@", self.stringProperty); /* Return value for our block object */
return NSOrderedSame;
}]; }
@end
然而在独立 Block Object 内部,你不能使用 dot notation 读写一个已声明属性:
void (^correctBlockObject)(id) = ^(id self){ NSLog(@"self = %@", self);
/* Should use setter method instead of this */
self.stringProperty = @"Block Objects"; /* Compile-time Error */ /* Should use getter method instead of this */ NSLog(@"self.stringProperty = %@",
self.stringProperty); /* Compile-time Error */
};
在这个场景中可以使用这个合成属性的 getter and setter 方法来代替 dot notation:
void (^correctBlockObject)(id) = ^(id self){ NSLog(@"self = %@", self);
/* This will work fine */
[self setStringProperty:@"Block Objects"]; /* This will work fine as well */ NSLog(@"self.stringProperty = %@",
[self stringProperty]);
};