3

当使用带有完成处理程序(如 AVAssetExportSession)异步返回的 Objective-C 对象时,这样的代码是否有任何错误:

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

Instruments 将 exportSession 报告为泄漏。我自己也有一些使用相同方法的类,它们也被报告为泄漏。

从我读过的所有内容来看,代码似乎应该遵循正确的内存管理规则,但必须有一些东西。我找到了这篇文章的链接,但我认为我不会导致循环保留。

4

1 回答 1

6

Objective-C 中的块自动获取其范围内的对象的所有权,并且您确实会导致循环引用。您的块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将由块保持活动状态,而块本身将由对象保持活动状态。

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

于 2010-09-13T04:50:34.067 回答