NSString для CFStringRef и CFStringRef для NSString в ARC?
Я пытаюсь понять правильный способ получения NSString
из CFStringRef
в ARC? То же самое для перехода в противоположном направлении, CFStringRef
в NSString
в ARC?
Каков правильный способ сделать это без создания утечек памяти?
- NSString: простой способ удалить аккорды UTF-8 из строки?
- Как получить ключ в объекте JavaScript по его значению?
- Как обновить «массив объектов» с помощью Firestore?
- Прослушать изменение значения моего текстового поля
- Как перебирать ключи объектов с помощью * ngFor?
- Как сохранить пользовательский ArrayList на экране Android?
- Что такое classы, ссылки и объекты?
- Сравните текущее время с двумя строками раз в день
- Как преобразовать значение NSString в NSData?
- Как удалить пробелы с правого конца NSString?
- Как отсортировать массив объектов в Java?
- хранить и извлекать объект classа по общим предпочтениям
- Рендеринг свойств объекта в реактиве
типично
NSString *yourFriendlyNSString = (__bridge NSString *)yourFriendlyCFString;
а также
CFStringRef yourFriendlyCFString = (__bridge CFStringRef)yourFriendlyNSString;
Теперь, если вы хотите знать, почему __bridge
ключевое слово __bridge
, вы можете обратиться к документации Apple . Там вы найдете:
__bridge
передает указатель между Objective-C и Core Foundation без передачи права собственности.
__bridge_retained
илиCFBridgingRetain
указатель Objective-C указателю Core Foundation, а также передает вам право собственности. Вы несете ответственность за вызов CFRelease или связанной функции, чтобы отказаться от владения объектом.
__bridge_transfer
илиCFBridgingRelease
перемещает указатель не Objective-C в Objective-C, а также передает права собственности ARC. ARC отвечает за отказ от владения объектом.
Это означает, что в вышеуказанных случаях вы бросаете объект без изменения права собственности. Это подразумевает, что ни в одном случае вы не будете контролировать обработку строк.
Также может быть случай, когда вы хотите передать право собственности по какой-либо причине.
Например, рассмотрим следующий fragment
- (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
, передав право собственности при кастинге.
- (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
используя __bridge_retained
, так что вы будете владеть объектом, и вам придется явно освободить его, используя CFRelease
.
Чтобы обернуть его, вы можете
NSString → CFString
// Don't transfer ownership. You won't have to call `CFRelease` CFStringRef str = (__bridge CFStringRef)string; // Transfer ownership (ie 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;