Когато използвате обект 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];
}];
Инструментите докладват exportSession като изтичане. Аз също имам няколко класа, които използват една и съща методология и те също се отчитат като течове.
От всичко, което съм прочел, изглежда, че кодът трябва да следва правилните правила за управление на паметта, но нещо трябва да е нагоре тази статия, но не мисля, че причинявам циклично задържане.
Отговори:
6 за отговор № 1Блокове в 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
ще бъде запазен жив от блока, а самият блок ще бъде запазен жив от обекта.
Когато се занимавате с блокове, ви предлагам да използвате събраната от боклука среда.