block 是 Apple 在 GCC 4.2 中扩充的新语法特性,其目的是支持多核并行编程。我们可以将 dispatch_queue 与 block 结合起来使用,方便进行多线程编程。
本文源代码下载:点击下载
1,实验工程准备
在 XCode 4.0 中,我们建立一个 Mac OS X Application 类型的 Command Line Tool,在 Type 里面我们选择 Foundation 就好,工程名字暂且为 StudyBlocks.默认生成的工程代码 main.m 内容如下:
int main (int argc, const char * argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; // insert code here... NSLog(@"Hello, World!"); [pool drain]; return 0; }
void (^aBlock)(void) = ^(void){ NSLog(@"Hello, World!"); }; aBlock();用上面的这两行语句替换 main.m 中的 NSLog(@"Hello, World!"); 语句,编译运行,结果是一样的。
void (^aBlock)(void) = 0; aBlock = ^(void){ NSLog(@" >> Hello, World!"); }; aBlock();
void (^blocks[2])(void) = { ^(void){ NSLog(@" >> This is block 1!"); }, ^(void){ NSLog(@" >> This is block 2!"); } }; blocks[0](); blocks[1]();
dispatch_block_t block; if (x) { block = ^{ printf("true\n"); }; } else { block = ^{ printf("false\n"); }; } block();
if (x) { struct Block __tmp_1 = ...; // setup details block = &__tmp_1; } else { struct Block __tmp_2 = ...; // setup details block = &__tmp_2; }
__block int blockLocal = 100; static int staticLocal = 100; void (^aBlock)(void) = ^(void){ NSLog(@" >> Sum: %d\n", global + staticLocal); global++; blockLocal++; staticLocal++; }; aBlock(); NSLog(@"After modified, global: %d, block local: %d, static local: %d\n", global, blockLocal, staticLocal);
// 1 void (^aBlock)(int) = 0; static void (^ const staticBlock)(int) = ^(int i) { if (i > 0) { NSLog(@" >> static %d", i); staticBlock(i - 1); } }; aBlock = staticBlock; aBlock(5); // 2 __block void (^blockBlock)(int); blockBlock = ^(int i) { if (i > 0) { NSLog(@" >> block %d", i); blockBlock(i - 1); } }; blockBlock(5);
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; initData(); // create dispatch queue // dispatch_queue_t queue = dispatch_queue_create("StudyBlocks", NULL); dispatch_async(queue, ^(void) { int sum = 0; for(int i = 0; i < Length; i++) sum += data[i]; NSLog(@" >> Sum: %d", sum); flag = YES; }); // wait util work is done. // while (!flag); dispatch_release(queue); [pool drain];
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; initData(); // Create a semaphore with 0 resource // __block dispatch_semaphore_t sem = dispatch_semaphore_create(0); // create dispatch semaphore // dispatch_queue_t queue = dispatch_queue_create("StudyBlocks", NULL); dispatch_async(queue, ^(void) { int sum = 0; for(int i = 0; i < Length; i++) sum += data[i]; NSLog(@" >> Sum: %d", sum); // signal the semaphore: add 1 resource // dispatch_semaphore_signal(sem); }); // wait for the semaphore: wait until resource is ready. // dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER); dispatch_release(sem); dispatch_release(queue); [pool drain];
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; initData(); __block int sum = 0; // Create a semaphore with 0 resource // __block dispatch_semaphore_t sem = dispatch_semaphore_create(0); __block dispatch_semaphore_t taskSem = dispatch_semaphore_create(0); // create dispatch semaphore // dispatch_queue_t queue = dispatch_queue_create("StudyBlocks", NULL); dispatch_block_t task1 = ^(void) { int s = 0; for (int i = 0; i < Length; i++) s += data[i]; sum = s; NSLog(@" >> after add: %d", sum); dispatch_semaphore_signal(taskSem); }; dispatch_block_t task2 = ^(void) { dispatch_semaphore_wait(taskSem, DISPATCH_TIME_FOREVER); int s = sum; for (int i = 0; i < Length; i++) s -= data[i]; sum = s; NSLog(@" >> after subtract: %d", sum); dispatch_semaphore_signal(sem); }; dispatch_async(queue, task1); dispatch_async(queue, task2); // wait for the semaphore: wait until resource is ready. // dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER); dispatch_release(taskSem); dispatch_release(sem); dispatch_release(queue); [pool drain];
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; initData(); dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); __block int sum = 0; __block int *pArray = data; // iterations // dispatch_apply(Length, queue, ^(size_t i) { sum += pArray[i]; }); NSLog(@" >> sum: %d", sum); dispatch_release(queue); [pool drain];
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; initData(); __block int sum = 0; // Create a semaphore with 0 resource // __block dispatch_semaphore_t taskSem = dispatch_semaphore_create(0); // create dispatch semaphore // dispatch_queue_t queue = dispatch_queue_create("StudyBlocks", NULL); dispatch_group_t group = dispatch_group_create(); dispatch_block_t task1 = ^(void) { int s = 0; for (int i = 0; i < Length; i++) s += data[i]; sum = s; NSLog(@" >> after add: %d", sum); dispatch_semaphore_signal(taskSem); }; dispatch_block_t task2 = ^(void) { dispatch_semaphore_wait(taskSem, DISPATCH_TIME_FOREVER); int s = sum; for (int i = 0; i < Length; i++) s -= data[i]; sum = s; NSLog(@" >> after subtract: %d", sum); }; // Fork dispatch_group_async(group, queue, task1); dispatch_group_async(group, queue, task2); // Join dispatch_group_wait(group, DISPATCH_TIME_FOREVER); dispatch_release(taskSem); dispatch_release(queue); dispatch_release(group); [pool drain];
http://developer.apple.com/library/ios/#documentation/General/Conceptual/ConcurrencyProgrammingGuide/Introduction/Introduction.html