[objective-c] 아크와 브리지 캐스트

ARC으로, 나는 더 이상 캐스팅 할 수 없습니다 CGColorRefid. 브리지 캐스트를해야한다는 것을 알게되었습니다. clang 문서 에 따르면 :

브리지 캐스트는 C 스타일 캐스트는 세 가지 키워드 중 하나의 주석을 붙일 수 :

(__bridge T) op피연산자를 대상 유형으로 캐스팅합니다 T. 경우 T
보존 가능한 개체 포인터 유형이 다음 op비 보존 가능한 포인터 타입이 있어야합니다. 경우 T비 보존 가능한 포인터 타입이며, 다음 작전은 보존 가능한 개체 포인터 유형이 있어야합니다. 그렇지 않으면 캐스트가 잘못 형성됩니다. 소유권 이전이 없으며 ARC는 보유 작업을 삽입하지 않습니다.

(__bridge_retained T) op유지할 수있는 객체 포인터 유형을 가져야하는 피연산자를 대상 유형으로 캐스트 할 수없는 대상 유형으로 캐스트합니다. ARC는 로컬 값에 대한 일반적인 최적화에 따라 값을 유지하며 수신자는 +1의 균형을 맞 춥니 다.

(__bridge_transfer T) op유지할 수없는 포인터 유형을 가져야하는 피연산자를 대상 유형으로 캐스트합니다.이 유형은 보유 가능한 객체 포인터 유형이어야합니다. ARC는 로컬 값에 대한 일반적인 최적화에 따라 둘러싸는 전체 표현이 끝나면 값을 해제합니다.

이러한 캐스트는 ARC 제어 안팎으로 오브젝트를 전송하기 위해 필요합니다. 보유 가능한 객체 포인터의 변환에 대한 섹션의 이론적 근거를 참조하십시오.

ARC가 불균형 유지 또는 방출을 각각 방출하도록 설득하기 위해 순수하게 __bridge_retained또는 __bridge_transfer캐스트를 사용하는 것은 좋지 않은 형태입니다.

어떤 상황에서 각각을 사용해야합니까?

예를 들어, CAGradientLayer가지고 colors배열 허용 속성 CGColorRef들. 내 생각에 나는 __brige여기서 사용해야 하지만 정확히 왜 내가 해야하는지 (또는 그렇지 않아야하는지) 불분명합니다.



답변

설명이 혼란 스럽다는 데 동의합니다. 방금 그들을 잡았으므로 요약하려고합니다.

  • (__bridge_transfer <NSType>) op또는 대안 으로 ARC로 전송 CFBridgingRelease(op)하는 CFTypeRef동안 보유 횟수를 소비하는 데 사용됩니다 . 이것은 또한id someObj = (__bridge <NSType>) op; CFRelease(op);

  • (__bridge_retained <CFType>) op또는 대안 으로 +1 보유 카운트를 제공하면서 CF 랜드 CFBridgingRetain(op)NSObject오버 오버 를 넘겨주는 데 사용됩니다 . 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를 colorsNSArray 로 리턴하는 것이 좋습니다 . 에서 ARC 릴리스 노트로 전환 섹션에서, 방법 등을 이용하여 지적한다 “컴파일러는 CF 코코아 방법에서 반환 된 개체 처리”-CGColor 하는 핵심 재단 객체가 자동으로 컴파일러에 의해 적절하게 처리됩니다 반환합니다.

따라서 다음과 같은 코드를 사용하는 것이 좋습니다.

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

현재 Apple의 예제 코드에 위에서 언급 한 (id) 캐스트가 누락되어 컴파일러 오류를 피하는 데 여전히 필요합니다.


답변