2010-09-13 23 views
3

当使用与一个完成处理程序,像AVAssetExportSession异步返回一个Objective-C的对象,有什么wronmg与这样的代码:解放出来对象

AVAssetExportSession* exportSession = [[AVAssetExportSession alloc] initWithAsset: composition presetName: AVAssetExportPresetHighestQuality]; 
[exportSession exportAsynchronouslyWithCompletionHandler: ^(void) { 
    // export completed 
    NSLog(@"Export Complete %d %@", exportSession.status, exportSession.error); 
    [exportSession release]; 
    }]; 

仪器报告exportSession作为泄漏。我也有几个我自己的课程使用相同的方法,他们也被报告为泄漏。

从我读过的所有东西看来,代码应该遵循正确的内存管理规则,但必须注意。我找到了this article的链接,但我认为我没有造成循环保留。

回答

6

在其范围内的对象的Objective-C automatically take ownership中的块,并且您确实会产生循环引用。您的区块隐含地保留exportSession,并且exportSession可能会保留您的区块。

内存管理规则说你应该尽快放弃对象的所有权。因此,在你的情况下,正确的地方是在致电exportAsynchronouslyWithCompletionHandler:之后。

AVAssetExportSession* exportSession = [[AVAssetExportSession alloc] initWithAsset: composition presetName: AVAssetExportPresetHighestQuality]; 
[exportSession exportAsynchronouslyWithCompletionHandler: ^(void) { 
    // export completed 
    NSLog(@"Export Complete %d %@", exportSession.status, exportSession.error); 
}]; 
[exportSession release]; 

循环引用应该是显而易见的方式:exportSession将由块保持活着,和块本身将被对象保持活。

当你处理块时,我建议你使用垃圾收集环境。

+3

问题是,这是iPhone编程,因为没有GC。使导出会话成为'__block'变量。这会导致它不保留导出会话,从而消除循环。它不应该引起任何问题,因为exportSession本身必须调用处理程序,因此它当时仍然保持活跃状态​​。 – 2010-09-13 05:07:03

+0

感谢你们,在对象上使用__block(例子中的AVAssetExportSession)并在块中释放它,就像问题一样,似乎可行。 (如果该块没有保留该对象,我认为我必须等到该块完成释放该对象。) – 2010-09-13 06:37:23

+0

@James Veenstra如果这解决了您的问题,请考虑检查除了问题之外的“接受”标记得分了。 – zneak 2010-09-13 22:18:17