您的位置:首页 > 移动开发

测试Apple LLVM中所引入的Blocks机制是否具有闭包特性

2012-07-19 17:59 405 查看
Apple从OS X Snow Leopard开始(OS X 10.6)以及iOS 4.0开始,在其编译器内引入了Blocks语法特性,使其在C++11标准发布之前就能有Lambda表达式可用了,呵呵~但是其是否是一个闭包(Closure)呢?我们不妨可以测试一下:

#import <Foundation/Foundation.h>

static void __attribute__((noinline)) (^MyTest(void))(void)
{
__block int a = 100;
int b = 200;

NSLog(@"address of a is: 0x%.16lX", (unsigned long)&a);
NSLog(@"address of b is: 0x%.16lX", (unsigned long)&b);

void (^block)(void) = ^void(void){
a += 300;
NSLog(@"The value is: %d", a + b);

NSLog(@"address of a is: 0x%.16lX", (unsigned long)&a);
NSLog(@"address of b is: 0x%.16lX", (unsigned long)&b);
};

a = 0;
b = 0;

return Block_copy(block);
}

int main (int argc, const char * argv[])
{
@autoreleasepool
{
// insert code here...
void (^block)(void) = MyTest();

block();

// Disrupt the stack space
NSLog(@"int = %d, double = %f, long long = %lld", 100, 300.057, 12345677654321LL);

block();

Block_release(block);
}

return 0;
}


以上代码基于OS X Lion,64位应用。 我们可以通过上述输出得知,第一次调用block之前,a的值为0,b为200,b不受MyTest后面赋值的影响,而只是将定义此Block之前的值传给它。而a的变动是受到影响的。因此第一次调用block之后,a变为300,输出500;而第二次调用Block之后,a变为了600,输出800。

因此,Objective-C里的Block满足闭包的定义。但是这里有一个注意点——Blocks默认是分配在栈上的,因此如果要作为返回值返回或作为函数参数,则必须用Block_copy来进行复制。使用结束后必须用Block_release来进行释放。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: