- (double) detectCollisionsInArray:(NSArray*)objects { int count = [objects count]; if (count > 0) { double time = CFAbsoluteTimeGetCurrent(); for (int i = 0; i < count; i++) { for (int j = i + 1; j < count; j++) { /** LOTS AND LOTS OF WORK FOR EACH OBJECT **/ } } return CFAbsoluteTimeGetCurrent() - time; } return 0; }
相当直截了当,考虑到问题的限制,它似乎表现良好.但是,我想利用每个对象的状态在代码段中不被修改,并使用GCD来并行化这个工作.为此,我正在尝试这样的事情:
- (double) detectCollisionsInArray:(NSArray*)objects { int count = [objects count]; if (count > 0) { NSOperationQueue* opQueue = [[NSOperationQueue alloc] init]; NSBlockOperation* blockOperation = nil; double time = CFAbsoluteTimeGetCurrent(); for (int i = 0; i < count; i++) { for (int j = i + 1; j < count; j++) { void (^workBlock) (void) = ^() { /** LOTS AND LOTS OF WORK FOR EACH OBJECT **/ }; if (!blockOperation) { blockOperation = [NSBlockOperation blockOperationWithBlock:b]; } else { [blockOperation addExecutionBlock:workBlock]; } } } [opQueue addOperation:blockOperation]; [opQueue autorelease]; return CFAbsoluteTimeGetCurrent() - time; } return 0; }
任何人都可以帮助我走上正确的轨道,或者提供一个良好的GCD教程的链接?我已经浏览了几个GCD教程,并扫描了所有的文档,我仍然觉得我对这个问题的掌握至关重要.谢谢!
解决方法
- (double) detectCollisionsInArray:(NSArray*)objects { int count = [objects count]; if (count > 0) { double time = CFAbsoluteTimeGetCurrent(); dispatch_group_t group = dispatch_group_create(); dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0); for (int i = 0; i < count; i++) { dispatch_group_async(group,queue,^{ for (int j = i + 1; j < count; j++) { dispatch_group_async(group,^{ /** LOTS AND LOTS OF WORK FOR EACH OBJECT **/ }); } }); } dispatch_group_wait(group,DISPATCH_TIME_FOREVER); dispatch_release(group); return CFAbsoluteTimeGetCurrent() - time; } return 0; }
您可以使用dispatch_group将所有执行组合在一起,并等待所有执行完成dispatch_group_wait.如果您不想知道块的完成情况,您可以忽略组件部分,只需使用dispatch_async. dispatch_get_global_queue函数将获得3个并发队列之一(低,默认或高优先级),以便将块提交到.你不必担心限制线程数或任何类似的事情. GCD调度程序应该为你做所有这些.只要确保提交到一个并发队列,它可以是3个全局队列之一,或者通过将DISPATCH_QUEUE_CONCURRENT传递给dispatch_queue_create创建的队列(这可以从OS X 10.7和iOS 5.0开始).
如果您在每个块中执行一些文件I / O或对某些其他资源征税,则可能需要在GCD中进行统计,并一次限制要提交到队列的块数.这将与限制NSOperationQueue中的并发操作计数具有相同的效果.您可以使用GCD信号量来做到这一点:
- (double) detectCollisionsInArray:(NSArray*)objects { int count = [objects count]; if (count > 0) { double time = CFAbsoluteTimeGetCurrent(); dispatch_group_t group = dispatch_group_create(); dispatch_semaphore_t semaphore = dispatch_semaphore_create(10); dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0); for (int i = 0; i < count; i++) { dispatch_semaphore_wait(semaphore,DISPATCH_TIME_FOREVER); dispatch_group_async(group,^{ for (int j = i + 1; j < count; j++) { dispatch_semaphore_wait(semaphore,DISPATCH_TIME_FOREVER); dispatch_group_async(group,^{ /** LOTS AND LOTS OF WORK FOR EACH OBJECT **/ dispatch_semaphore_signal(semaphore); }); } dispatch_semaphore_signal(semaphore); }); } dispatch_group_wait(group,DISPATCH_TIME_FOREVER); dispatch_release(group); dispatch_release(semaphore); return CFAbsoluteTimeGetCurrent() - time; } return 0; }
一旦你得到它的悬挂,GCD是非常简单的使用.我现在使用它在我的代码.
Can anyone help to put me on the right track and perhaps provide a link to a good GCD tutorial?
运行,不要走到Mike Ash’s blog.他的GCD系列是我看到的最清晰和最简洁的,只需要你大约30分钟来阅读整个事情.苹果的WWDC视频从2010年的GCD和块也不错.