ARC NSString
에서 를 얻는 올바른 방법을 이해하려고합니다 CFStringRef
. 반대 방향으로가는 대한 동일 CFStringRef
로 NSString
ARC에?
메모리 누수를 일으키지 않고이를 수행하는 올바른 방법은 무엇입니까?
ARC NSString
에서 를 얻는 올바른 방법을 이해하려고합니다 CFStringRef
. 반대 방향으로가는 대한 동일 CFStringRef
로 NSString
ARC에?
메모리 누수를 일으키지 않고이를 수행하는 올바른 방법은 무엇입니까?
retain
보내고 및 release
객체를 -ing, 우리는 지금 같은 "아름다운"캐스트를 사용해야합니다 __bridge_transfer
, __unsafe_unretained
하고 __autoreleasing
. 아무도 그럴 시간이 없습니다. (그리고 심각, 읽기가 더 어려워 제 생각에는, 그것은 전혀 메모리 관리를 용이하지 않았다..)
답변:
일반적으로
NSString *yourFriendlyNSString = (__bridge NSString *)yourFriendlyCFString;
과
CFStringRef yourFriendlyCFString = (__bridge CFStringRef)yourFriendlyNSString;
이제 __bridge
키워드가있는 이유를 알고 싶다면 Apple 문서를 참조하십시오 . 다음을 찾을 수 있습니다.
__bridge
소유권 양도없이 Objective-C와 Core Foundation간에 포인터를 전송합니다.
__bridge_retained
또는CFBridgingRetain
Objective-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
.
그것을 마무리하기 위해 당신은 가질 수 있습니다
// 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`
// 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;
NSString->CFString
, 우리는 사용해야합니다 __bridge
. 하지만 때 CFString->NSString
, 우리는 사용해야합니다 __bride_transfer
. ? 그리고 CFRelease
우리가 필요하지 않을 때 사용 하면 부작용 이 있습니다. 감사합니다 :)
CFRelease
유지 / 해제 작업으로 끝날 것이고 결국 NULL
포인터를 해제하기 때문에 추가 프로그램이 합리적으로 프로그램을 충돌시켜야합니다 .
CFStringRef foo (__bridge CFStringRef)theNSString;
와NSString *bar = (__bridge NSString *)theCFString;