开发者

Freeing Objects in Objective-C Blocks

When using an Objective-C object that returns asynchronously with a completion handler开发者_运维知识库, like AVAssetExportSession, is there anything wronmg with code like this:

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

Instruments reports exportSession as a leak. I've also got a few classes of my own that use the same methodology and they also get reported as leaks.

From everything I've read it seems like the code should follow the proper memory management rules but something must be up. I found a link to this article, but I don't think I'm causing Cyclic Retention.


Blocks in Objective-C automatically take ownership of objects in their scope, and you do cause a cyclic reference. Your block retains exportSession implicitly, and exportSession likely retains your block.

Memory management rules say you should relinquish ownership of objects as soon as you can. Therefore, the right place to do it, in your case, is after the call to exportAsynchronouslyWithCompletionHandler:.

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

The cyclic reference should be obvious that way: exportSession will be kept alive by the block, and the block itself will be kept alive by the object.

When you deal with blocks, I suggest you use the garbage collected environment.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜