释放Objective-C块中的对象

Jam*_*tra 3 iphone objective-c-blocks

当使用与完成处理程序异步返回的Objective-C对象(如AVAssetExportSession)时,有任何代码如下所示:

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

仪器将exportSession报告为泄漏.我也有一些我自己的类使用相同的方法,他们也被报告为泄漏.

从我读过的所有内容看来,代码应该遵循适当的内存管理规则,但必须要有一些东西.我找到了这篇文章的链接,但我认为我没有引起循环保留.

zne*_*eak 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];
Run Code Online (Sandbox Code Playgroud)

循环引用应该是明显的方式:exportSession将由块保持活动,并且块本身将由对象保持活动.

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

  • 问题是这是iPhone编程,因此没有GC.使导出会话成为`__block`变量.这将导致它不保留导出会话,从而消除循环.它不应该导致任何问题,因为exportSession本身必须调用处理程序,因此它保证在那时仍然存活. (3认同)