Правильный способ обработки CGImageRef в контейнерах под ARC

Я новичок в использовании дуги в моих проектах. Я пытаюсь понять __bridge и его маленьких друзей, чтобы я мог правильно использовать CGImageRef при добавлении и удалении их из контейнеров.

Я получаю "Потенциальную утечку хранящегося объекта…" на одной из моих строк. Вот основной цикл моего кода:

CGImageRef renderedRef = CGBitmapContextCreateImage(UIGraphicsGetCurrentContext());
[_array addObject: (__bridge_transfer id)renderedRef];//_array is an iVar

затем где-то по дороге я делаю это:

    CGImageRef iRef = (__bridge_retained CGImageRef)array[0];
//then I do something fancy with iRef
//at the end of the method, I get "Potential leak of an object stored…"
//I have no idea what to do
//I've tried CGImageRelease(iRef); but it still doesn't change the warning. 

Может кто-то пролить свет на это? Кроме того, я пробовал просто использовать __bridge, но это не имеет значения.

Изменить 1:

Я расширил результаты анализа и следил за тем, что происходило. Это потому, что я использовал iRef в таком методе: [self doSomethingFancy:iRef]; и в этом методе iRef был сохранен, но не выпущен. Так что это исправляет предупреждение, но я все еще немного озадачен.

Я не совсем понимаю, когда использовать различные __bridge-приведения. Под ARC, увеличивает ли следующий счетчик ссылок?

CGImageRef iRef = (__bridge CGImageRef)array[0];

Кроме того, в какой-то момент, если я скажу своему _array iVar удалить AllObjects, будет ли это правильно уменьшать количество ссылок?

1 ответ

Решение
// This WILL NOT increment the image's retain count.
CGImageRef iRef = (__bridge CGImageRef)array[0];

// This WILL increment the image's retain count.
CGImageRef iRef = (__bridge_retained CGImageRef)array[0];

поскольку __bridge_retained увеличивает счет сохранения, вам нужно уменьшить счет хранения через некоторое время. Так как __bridge_retained действует как CFRetainApple создала __bridge_retained обертка называется CFBridgingRetain это напоминает вам об этом:

// This WILL increment the image's retain count.
CGImageRef iRef = CFBridgingRetain(array[0]);

Всякий раз, когда вы видите CFRetain или же CFBridgingRetainвы знаете, что вам нужно отпустить объект в какой-то момент позже.

Точно так же вы можете использовать CFBridgingRelease вместо __bridge_transfer уменьшить количество сохраняемых объектов CF. Пример:

[_array addObject:CFBridgingRelease(renderedRef)];

Ты можешь использовать CFBridgingRelease сбалансировать CFRetain или CFBridgingRetain, Возвращает id что ARC управляет.

Нормальный NSMutableArray сохраняет каждый из его элементов. Вы можете сказать это, чтобы стать пустым:

[_array removeAllObjects];

Когда вы сделаете это, он освободит каждый из своих элементов, уравновешивая сохранение, которое он выполнил для каждого элемента.

Таким образом, в этом коде нет утечки памяти:

CGImageRef image = CGImageCreate(...);
[_array addObject:CFBridgingRelease(image)];
[_array removeAllObjects];

или в этом коде:

CGImageRef image = CGImageCreate(...);
[_array addObject:CFBridgingRelease(image)];

CGImageRef image2 = CFBridgingRetain([_array lastObject]);
[_array removeLastObject];
CGContextDrawImage(gc, rect, image2);
CGImageRelease(image2);
Другие вопросы по тегам