[objective-c] ARC의 NSString에서 CFStringRef로 및 CFStringRef에서 NSString으로?

ARC NSString에서 를 얻는 올바른 방법을 이해하려고합니다 CFStringRef. 반대 방향으로가는 대한 동일 CFStringRefNSStringARC에?

메모리 누수를 일으키지 않고이를 수행하는 올바른 방법은 무엇입니까?



답변

일반적으로

NSString *yourFriendlyNSString = (__bridge NSString *)yourFriendlyCFString;

CFStringRef yourFriendlyCFString = (__bridge CFStringRef)yourFriendlyNSString;

이제 __bridge키워드가있는 이유를 알고 싶다면 Apple 문서를 참조하십시오 . 다음을 찾을 수 있습니다.

__bridge 소유권 양도없이 Objective-C와 Core Foundation간에 포인터를 전송합니다.

__bridge_retained또는 CFBridgingRetainObjective-C 포인터를 Core Foundation 포인터로 캐스팅하고 소유권을 사용자에게 양도합니다. CFRelease 또는 관련 함수를 호출하여 개체의 소유권을 포기해야합니다.

__bridge_transfer또는 CFBridgingRelease비 Objective-C 포인터를 Objective-C로 이동하고 소유권을 ARC로 이전합니다. ARC는 객체의 소유권을 포기할 책임이 있습니다.

이는 위의 경우 소유권을 변경하지 않고 객체를 캐스팅한다는 것을 의미합니다. 이것은 두 경우 모두 문자열의 메모리를 처리 할 책임이 없음을 의미합니다.

어떤 이유로 든 소유권을 양도하려는 경우도있을 수 있습니다.

예를 들어 다음 스 니펫을 고려하십시오.

- (void)sayHi {
    CFStringRef str = CFStringCreateWithCString(NULL, "Hello World!", kCFStringEncodingMacRoman);

    NSString * aNSString = (__bridge NSString *)str;

    NSLog(@"%@", aNSString);

    CFRelease(str); //you have to release the string because you created it with a 'Create' CF function
}

CFRelease경우 캐스팅 할 때 소유권을 이전하여 a를 저장할 수 있습니다 .

- (void)sayHi {
    CFStringRef str = CFStringCreateWithCString(NULL, "Hello World!", kCFStringEncodingMacRoman);

    NSString * aNSString = (__bridge_transfer NSString *)str;
// or alternatively
    NSString * aNSString = (NSString *)CFBridgingRelease(str);

    NSLog(@"%@", aNSString);
}

의 소유권 str이 이전되었으므로 이제 ARC가 시작하여 메모리를 해제합니다.

반면에 캐스트 NSString *CFString사용하여 a를 __bridge_retained캐스트 할 수 있으므로 객체를 소유하고을 사용하여 명시 적으로 해제해야합니다 CFRelease.


그것을 마무리하기 위해 당신은 가질 수 있습니다

NSString → CFString

// Don't transfer ownership. You won't have to call `CFRelease`
CFStringRef str = (__bridge CFStringRef)string;

// Transfer ownership (i.e. get ARC out of the way). The object is now yours and you must call `CFRelease` when you're done with it
CFStringRef str = (__bridge_retained CFStringRef)string // you will have to call `CFRelease`

CFString → NSString

// Don't transfer ownership. ARC stays out of the way, and you must call `CFRelease` on `str` if appropriate (depending on how the `CFString` was created)
NSString *string = (__bridge NSString *)str;

// Transfer ownership to ARC. ARC kicks in and it's now in charge of releasing the string object. You won't have to explicitly call `CFRelease` on `str`
NSString *string = (__bridge_transfer NSString *)str;


답변