一、block的定义及优点
Apple文档说:
A block is an anonymous inline collection of code, and sometimes also called a "closure".
Block是一个C级别的语法以及运行时的一个特性,和标准C中的函数(函数指针)类似,但是其运行需要编译器和运行时支持。从ios4.0,Mac_OSX v10.6开始就很好的支持Block。
在其他语言和环境中,更流行的把一个block对象称为闭包(在javascript,java,scale,groovy等语言中都有)。
项目中感觉使用Block最大的便利就是简化的回调过程。以前使用UIView的动画,进程要控制动画结束后进行相应的处理。iOS 4.0之后,UIView新增了对Block的支持,现在只要使用简单的一个Block代码就可以在写动画的代码部分直接添加动画结束后的操作。
二、block的声明和定义
ex:
c函数指针和blocks调用
- int (*CFunc) (int a) //c函数指针
- int result = CFunc(10);
- int (^BFunc) (int a) //blocks定义
- int result = BFunc(10);
注意 :在声明时一个没有使用任何参数的block必须在参数列表上面用void标明。 但定义时可以省略:
- int (^myBlock)(void) = ^{
- return 20130212;
- };
三、使用block
1、定义并调用block
如果你声明了一个block作为变量,你可以把它作为一个函数来使用
- int (^oneFrom)(int) = ^(int anInt) { return anInt - 1; };
- NSLog("1 from 10 is %d", oneFrom(10)); // Prints "1 from 10 is 9"
2、block用作方法、函数(多线程,动画)的参数
Cocoa提供了一系列使用block的方法。你可以把一个block作为方法的参数就像其他参数那样。下面是zon的一个例子
- items = [items sortedArrayUsingComparator:^(id item1, id item2) {
- EPGItem *epg1 = item1;
- EPGItem *epg2 = item2;
- // NSComparisonResult is a typedef for int
- NSComparisonResult result = [[NSNumber numberWithFloat:[[epg2 score] floatValue]] compare:[NSNumber numberWithFloat:[[epg1 score] floatValue]]];
- if (result) {
- return result;
- }
- return (NSComparisonResult)NSOrderedSame; // NSOrderedSame == 0
- }];
(NSArray *)sortedArrayUsingComparator:(NSComparator)cmptr NS_AVAILABLE(10_6, 4_0);
typedef NSComparisonResult (^NSComparator)(id obj1, id obj2);
3、block代替delegate
简化的回调过程
- typedef void (^SRRefreshBlock)(NLPullRefreshView* sender);
- @interface NLPullRefreshView : UIView {
- @property (nonatomic, copy) SRRefreshBlock block;
- @property(nonatomic,weak) NSObject <NLPullRefreshViewDelegate> *delegate;
- @end
- @protocol NLPullRefreshViewDelegate
- - (void)nlRefreshTableHeaderDidTriggerRefresh:(NLPullRefreshView*)view;
- @end
- @implementation NLPullRefreshView{
- - (void)pullApart:(NLPullRefreshView*)refreshView
- {
- if ([_delegate respondsToSelector:@selector(nlRefreshTableHeaderDidTriggerRefresh:)]) {
- [(id)_delegate performSelector:@selector(nlRefreshTableHeaderDidTriggerRefresh:)
- withObject:self
- afterDelay:0.0];
- }
- if (_block) {
- _block(self);
- }
- }
- }
四、block注意点
1、block文本(即, ^{ ... }) 是表示block的局部栈数据结构(stack-local data structure)的地址.
所以这些栈数据仅在当前声明的范围内有效,必须避免如下的使用:
- void dontDoThis() {
- void (^blockArray[3])(void); // an array of 3 block references
- for (int i = 0; i < 3; ++i) {
- blockArray[i] = ^{ printf("hello, %d\n", i); };
- // WRONG: The block literal scope is the "for" loop
- }
- }
- void dontDoThisEither() {
- void (^block)(void);
- int i = random():
- if (i > 1000) {
- block = ^{ printf("got i at: %d\n", i); };
- // WRONG: The block literal scope is the "then" clause
- }
- // ...
- }
2、
一个Block的内部时可以引用自身作用域外的变量的,包括static变量(RW),extern变量(RW)或自由变量(R),对于自由变量,在Block中只读的。在引入block的同时,还引入了一种特殊的__block关键字变量存储修饰符,指自由变量拥有读写权限:
- __block int x = 123;
- // x lives in block storage
- void (^printXAndY)(int) = ^(int y) {
- x = x + y;
- NSLog("%d %d\n", x, y);
- };
- DoSomethingManager *manager = [[DoSomethingManager alloc] init];
- manager.complete = ^{
- //...complete actions
- [manager otherAction];
- manager.complete = nil;
- [manager release];
- };
- DoSomethingManager *manager = [[DoSomethingManager alloc] init];
- manager.complete = ^{
- //...complete actions
- [manager otherAction];
- manager.complete = nil;
- };
- __block DoSomethingManager *manager = [[DoSomethingManager alloc] init];
- manager.complete = ^{
- //...complete actions [
- manager otherAction];
- manager = nil;
- };
- MyObject *object = [[MyObject alloc] init];
- object.str = @"hoge";
- __weak MyObject *weakObject = object;
- object.block = ^{
- MyObject strongObject = weakObject;
- if (strongObject) {
- NSLog(@"block: str=%@", strongObject.str);
- }
- };
转载 -- http://www.apkbus.com/android-128123-1-1.html