Работает ли ARC с объектами Core Graphics? - PullRequest
17 голосов
/ 18 октября 2011

Я недавно запустил новый проект с использованием автоматического подсчета ссылок (ARC).
Когда я присвоил содержимое CALayer:

UIView* view = ...
UIImage* image = ...
view.layer.contents = image.CGImage

Я получил ошибку

Неявное преобразование типа указателя не Objective C 'CGImageRef' в 'id' запрещено с ARC

Простое приведение CGImageRef к id скрывает ошибку, но мне было интересноесли ARC все еще функционирует правильно тогда?

Ответы [ 3 ]

43 голосов
/ 18 октября 2011

Вы действительно должны посмотреть видео ARC с WWDC 2011. Они доступны на сайте разработчика и открываются через iTunes.В частности:

• Сессия 323 - Представление автоматического подсчета ссылок

• Сессия 322 - Достижения Objective-C в глубине

Кроме того, справочные примечания ARC:

https://developer.apple.com/library/content/releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html

В справочных примечаниях и видеороликах обсуждается Core Graphics (и др.) И то, как они работают с ARC.

В частности, обратите внимание на раздел под названием «Управление бесплатными мостами»

Во многих приложениях Какао вам необходимо использовать объекты Core Foundation-style,будь то из самой платформы Core Foundation (такой как CFArrayRef или CFMutableDictionaryRef) или из платформ, которые принимают соглашения Core Foundation, такие как Core Graphics (вы можете использовать такие типы, как CGColorSpaceRef и CGGradientRef).

Компилятор не управляетвремя жизни объектов Core Foundation;Вы должны вызывать CFRetain и CFRelease (или соответствующие варианты, зависящие от типа) в соответствии с правилами управления памятью Core Foundation (см. Руководство по программированию управления памятью для Core Foundation).

Если вы выполняете приведение между Objective-C и CoreОбъекты в стиле Foundation, вы должны сообщить компилятору о семантике владения объектом, используя приведение (определенное в objc / runtime.h) или макрос в стиле Core Foundation (определенный в NSObject.h): [...]

У Йорга Якобсена также есть краткий обзор вариантов мостовых соединений: Управление бесплатными мостовыми соединениями в среде ARC * .

__bridge_retained (nb: используйте его только при приведении от указателя объекта к указателю типа C): мне (программисту) нужно некоторое время ссылаться на этот объект в темном мире указателей типа C, который непрозрачен дляты, ARC.Поэтому, пожалуйста, не отпускайте этот объект, пока он мне еще нужен.Я (программист) обещаю выпустить его сам (в темном мире), когда я закончу с этим

__ bridge_transfer (nb: используйте его только при приведении указателя типа C к объектууказатель): Я (программист) передаю вам, ARC, объект, которым я владею и который меня больше не интересует в темном мире указателей типа C, который непрозрачен для вас.Всякий раз, когда вы, ARC, закончите работу с этим объектом, пожалуйста, отпустите его сами, потому что вы знаете правильное время и, таким образом, избавляете меня от необходимости выполнять его самостоятельно.

__ bridge : ARC,Вы продолжаете балансировать свои удержания и выпуски, а я продолжаю балансировать свои в темном мире указателей типа C, который ...Всякий раз, когда мне нужно держаться за объект в темном мире, я сохраню его сам и освобождаю, когда это необходимо.Мне не нужен дополнительный контракт с тобой, АРК.

8 голосов
/ 20 октября 2011

Несмотря на ссылки, указанные Стивом, я считаю, что приведенный выше случай может быть особенным. Из примечаний к выпуску Переход к ARC обратите внимание на раздел «Компилятор обрабатывает объекты CF, возвращенные из методов какао»:

Компилятор понимает методы Objective C, которые возвращают Core Типы основания соответствуют историческим соглашениям об именах Какао (см. Расширенное руководство по программированию управления памятью). Например, Компилятор знает, что в iOS CGColor возвращается CGColor Метод UIColor не принадлежит.

Пример кода, который они предоставляют:

gradientLayer.colors = [NSArray arrayWithObjects:(id)[[UIColor darkGrayColor] CGColor],
                                                 (id)[[UIColor lightGrayColor] CGColor], nil];

опирается на известное возвращение CGColors из этих методов (в них отсутствует приведение к идентификатору, которое я добавил в приведенном выше коде, что должно быть исправлено в их документации в ближайшее время).

Поскольку [image CGImage] следует соглашениям о присвоении имен, я считаю, что CGImage будет правильно соединен здесь. Я думаю, что ваше приведение к id должно быть всем, что вам нужно здесь.

4 голосов
/ 25 октября 2011

Один популярный ответ на layer.contents = (id)image.CGImage вопрос - layer.contents = obj_unretainedObject(image.CGImage).

Я делаю =(__bridge id)image.CGImage.

...