С АРК, я больше не могу бросить CGColorRef
в id
. Я узнал, что мне нужно сделать актерский состав. В соответствии с Clang Docs :
Приведение с мостом - это приведение в стиле C, снабженное одним из трех ключевых слов:
(__bridge T) op
переводит операнд в тип назначенияT
. ЕслиT
это указатель типа сохраняемого объекта, то онop
должен иметь указатель типа без возможности сохранения. ЕслиT
это тип указателя с сохранением, то у op должен быть тип указателя с сохранением объекта. В противном случае актерский состав плохо сформирован. Передача права собственности не производится, и ARC не вводит операции по сохранению.
(__bridge_retained T) op
преобразует операнд, который должен иметь тип указателя сохраняемого объекта, в тип назначения, который должен быть типом указателя без возможности сохранения. ARC сохраняет значение при условии обычной оптимизации локальных значений, и получатель отвечает за балансирование этого +1.
(__bridge_transfer T) op
преобразует операнд, который должен иметь тип указателя без возможности сохранения, в тип назначения, который должен быть типом указателя сохраняемого объекта. ARC выпустит значение в конце полного выражения при условии обычной оптимизации локальных значений.Эти приведения необходимы для передачи объектов в ARC-контроль и обратно; см. обоснование в разделе о преобразовании указателей сохраняемых объектов.
Использование
__bridge_retained
или__bridge_transfer
приведение только для того, чтобы убедить ARC испустить несбалансированное удержание или освобождение, соответственно, является плохой формой.
В каких ситуациях я бы использовал каждый?
Например, CAGradientLayer
имеет colors
свойство, которое принимает массив CGColorRef
s. Я думаю, что я должен использовать __brige
здесь, но точно, почему я должен (или не должен) неясно.
Ответы:
Я согласен, что описание сбивает с толку. Так как я только что понял их, я постараюсь подвести итог:
(__bridge_transfer <NSType>) op
или, в качестве альтернативыCFBridgingRelease(op)
, используется, чтобы использовать счет удержанияCFTypeRef
при передаче его в ARC. Это также может быть представленоid someObj = (__bridge <NSType>) op; CFRelease(op);
(__bridge_retained <CFType>) op
или, в качестве альтернативыCFBridgingRetain(op)
, используется дляNSObject
передачи на CF-землю, в то же время давая ему +1 счет удержания. Вы должны обращаться сCFTypeRef
созданным вами способом так же, как с результатомCFStringCreateCopy()
. Это также может быть представленоCFRetain((__bridge CFType)op); CFTypeRef someTypeRef = (__bridge CFType)op;
__bridge
просто бросает между указателем-землей и объектом-землей Objective-C. Если у вас нет желания использовать приведенные выше преобразования, используйте этот.Может быть, это полезно. Сам я предпочитаю
CFBridging…
макросы немного более простым броскам.источник
В документации iOS я нашел другое объяснение, которое, по-моему, легче понять:
__bridge
передает указатель между Objective-C и Core Foundation без передачи права собственности.__bridge_retained (CFBridgingRetain)
Направляет указатель Objective C на указатель Core Foundation, а также передает право собственности на вас.Вы несете ответственность за вызов CFRelease или связанной функции, чтобы отказаться от владения объектом.
__bridge_transfer (CFBridgingRelease)
перемещает не-Objective-C указатель на Objective-C, а также передает владение ARC.ARC отвечает за отказ от владения объектом.
Источник: бесплатные мостовые типы
источник
Как продолжение, в этом конкретном случае, если вы работаете на iOS, Apple рекомендует использовать UIColor и его
-CGColor
метод для возврата CGColorRef вcolors
NSArray. В примечаниях к выпуску « Переход к ARC» в разделе «Компилятор обрабатывает объекты CF, возвращенные из методов какао», указано, что использование метода, подобного-CGColor
возвращающему объект Core Foundation, будет автоматически обрабатываться компилятором должным образом.Таким образом, они предлагают использовать код, подобный следующему:
Обратите внимание, что на данный момент в примере кода Apple отсутствует приведенное выше приведение (id), которое все еще необходимо, чтобы избежать ошибки компилятора.
источник