이해bridge,__bridge_transfer 및bridge_retained

2449 단어
전재자: 이해bridge,__bridge_transfer 및bridge_retained
===========아래 설명 없이 모두 ARC 환경에서 ==============
코코아 응용 프로그램에서 우리는 코아 Foundation-style objects, 예를 들어 CFArrayRef 또는 CFMutableDictionaryRef 등을 자주 사용한다.
컴파일러는 Core Foundation-style objects의 생명 주기를 자동으로 관리하지 않습니다. Core Foundation의 메모리 관리 규칙에 따라 CFRetain과 CFRelease(또는 상응하는 변체)를 호출해야 합니다.
Objective-C와CoreFoundation-style 대상 사이를 변환하려면 컴파일러 대상의 소유자에게 다음 매크로를 통해 알려야 합니다
  • __bridgeObjective-C와CoreFoundation지침을 전환하여 보유권을 이관하지 않습니다.
  • __bridge_retained 또는 CFBridgingRetainObjective-C 포인터를 Core Foundation 포인터로 전환하여 보유권을 이관한다.너는 대상을 방출하기 위해 CFRelease 또는 관련 함수를 호출하는 것을 책임져야 한다.
  • __bridge_transfer 또는 CFBridgingRelease 비Objective-C 포인터를 Objective-C 포인터로 전달하고 ARC.ARC는 객체를 해제합니다.

  • ===========이상은 애플 문서의 설명입니다. 다음은 예를 들어 설명합니다==============
    대상과 c 언어 포인터가 서로 변환될 때 다음과 같다.
        id obj = [[NSObject alloc]init];    
        void *p = (__bridge void *)(obj);
    

    컴파일러는 삽입(__bridge void *)을 강제로 변환하라고 알릴 수 있지만 __bridge는 안전하지 않습니다. 관리할 때 대상의 소유자를 주의하지 않으면 현수 바늘로 인해 프로그램이 붕괴됩니다.예컨대 아래의 이 코드
        void *p = 0;    {        
              id obj = [[NSObject alloc]init]; 
              p = (__bridge void *)(obj);   
        }        
        NSLog(@"class = %@",[(__bridge id)p class]);
    
    __bridge는 간단하게 지침 전환을 했을 뿐 보유권을 넘겨주지 않았기 때문에 역할 영역 밖의obj가 방출되었다. p는 이미 방출된 메모리를 가리키는 것이기 때문에 역할 영역 밖의op는 붕괴될 것이다.
    우리는 위의 __bridge__bridge_retained로 수정하면 문제를 해결할 수 있다.작용 영역 내에서 p에 대해 retain 조작을 한 셈이다.obj의 인용계수는 2이고 작용역이 끝날 때obj가 방출되며 인용계수는 1이 됩니다. p는 여전히 대상을 가지고 있습니다. 사용한 후에 CFRelease(p)방출p를 호출해야 합니다. ARC는 책임을 지지 않습니다.__bridge_transfer는 정반대__bridge_retained와 반대로 CF 대상이 OC 대상으로 전환될 때 전환된 변수가 보유한 대상은 이 변수가 전환 목표 변수에 부여된 후에 방출된다.
    다음은 예시 분석을 통해bridge_transfer
        CFMutableArrayRef cfObject = CFArrayCreateMutable(kCFAllocatorDefault, 0, NULL);    
        printf("retain count = %ld
    ",CFGetRetainCount(cfObject)); id obj = CFBridgingRelease(cfObject); printf("retain count after the cast = %ld
    ",CFGetRetainCount(cfObject));

    인쇄 정보:
    retain count = 1 retain count after the cast = 1
    캐스트 때 cfObject의 보유권이 ARC에 넘어갔으니 obj의 석방을 책임질 필요가 없습니다.

    좋은 웹페이지 즐겨찾기