使用Objective C中的块编程进行内存管理

Evi*_*oer 5 iphone multithreading ios objective-c-blocks

我正在调度队列中的完成块上阅读以下Apple文档,我无法理解其中的一部分.该文件提到,"为了防止过早释放队列,关键是要保持最初该队列,并释放它一旦完成块已经发出了." 这与我的理解相矛盾,即块在块闭包中保留了所有变量,块编程指南中提到了这些变量.

我在这里错过了什么?文档的片段粘贴在下面:

完成块只是您在原始任务结束时分派到队列的另一段代码.调用代码通常在完成任务时将完成块作为参数提供.所有任务代码必须做的是在完成其工作时将指定的块或函数提交到指定的队列.

清单3-4显示了使用块实现的平均功能.平均功能的最后两个参数允许调用者指定报告结果时要使用的队列和块.在averaging函数计算其值后,它会将结果传递给指定的块并将其分派到队列中.为防止队列过早释放,最初保留该队列并在分派完成块后释放该队列至关重要.清单3-4在任务之后执行完成回调

void average_async(int *data, size_t len, dispatch_queue_t queue, void (^block)(int))
{
   // Retain the queue provided by the user to make
   // sure it does not disappear before the completion
   // block can be called.
   dispatch_retain(queue);

   // Do the work on the default concurrent queue and then
   // call the user-provided block with the results.
   dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
   int avg = average(data, len);
   dispatch_async(queue, ^{ block(avg);});

   // Release the user-provided queue when done
   dispatch_release(queue);
   });
}
Run Code Online (Sandbox Code Playgroud)

ugh*_*fhw 3

这与我的理解相矛盾,即该块保留其闭包中的所有变量

这不是矛盾,而是误解。块保留它引用的所有Objective-C 对象。其他对象类型使用自己的保留函数而不是标准函数。因此,运行时不可能知道如何保留块可能包含的每个变量。这就是为什么需要手动保留和释放队列的原因。