NSMakeCollectable и ARC не работают

Я пытаюсь преобразовать свой старый проект в ARC. У меня есть функция, которая создает UUID, но, видимо, это больше не поддерживается при использовании ARC:

NSString *uuid = nil; CFUUIDRef theUUID = CFUUIDCreate(kCFAllocatorDefault); if (theUUID) { uuid = NSMakeCollectable(CFUUIDCreateString(kCFAllocatorDefault, theUUID)); //[uuid autorelease]; CFRelease(theUUID); } 

Я получаю ошибку компилятора (при попытке конвертировать): «NSMakeCollectable» недоступен: недоступен в режиме автоматического подсчета ссылок.

Поэтому мой вопрос: как мне создать UUID при использовании ARC? Есть ли другой способ, который я должен использовать?

NSMakeCollectable() предназначен для использования (по существу, устаревшего) сборщика мусора Objective-C. ARC ничего не знает об этом.

Вы должны использовать специальный атрибут casting, обычно __bridge_transfer , чтобы гарантировать, что память не будет протекать. __bridge_transfer используется так:

 id MakeUUID(void) { id result = nil; CFUUIDRef uuid = CFUUIDCreate(NULL); if (uuid) { result = (__bridge_transfer id)uuid; // this "transfers" a retain from CF's control to ARC's control. } return result; } 

Изменить . Как упоминалось в других ответах, CFBridgingRelease() делает это для вас. Поэтому вместо использования (__bridge_transfer id)uuid , может быть более CFBridgingRelease(uuid) писать CFBridgingRelease(uuid) . Они эквивалентны, так что это зависит от вас, что вы найдете более читаемым.

Когда вы переносите объект из CFString в NSString , вы должны позволить ARC знать, как вы хотите обрабатывать управление памятью. В этом случае я бы предложил:

 uuid = CFBridgingRelease(CFUUIDCreateString(kCFAllocatorDefault, theUUID)); 

Это дает команду CoreFoundation освободить объект (как это требуется для баланса Create ). Какао будет ARC-сохранить объект, когда он назначен uuid .

 CFUUIDRef theUUID = CFUUIDCreate(NULL); NSString *s2ndUuid = (__bridge_transfer NSString*)CFUUIDCreateString(kCFAllocatorDefault, theUUID); 

Чтобы иметь один UUID для всего приложения, я считаю, что лучший способ достичь этого – запустить его один раз в течение всего жизненного цикла приложения.

 static NSString *uuid; - (NSString *)theCurrentDeviceUniqueIdentifier { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ CFUUIDRef theUUID = CFUUIDCreate(kCFAllocatorDefault); if (theUUID) { uuid = CFBridgingRelease(CFUUIDCreateString(kCFAllocatorDefault, theUUID)); CFRelease(theUUID); } }); return uuid; } 

это определение NSMakeCollectable

 NS_INLINE id NSMakeCollectable(CFTypeRef cf) { return cf ? (id)CFMakeCollectable(cf) : nil; } 

Я думаю, это должно сработать

 uuid =CFUUIDCreateString(kCFAllocatorDefault, theUUID); 
  • Возможно передать в блоках без объекта __weak (iOS 5 + ARC)
  • Должен ли я использовать __bridge или __bridge_retained, если я соединяю автореализованный объект с Core Foundation?
  • CGImageDestinationCreateWithData не создает объект CGImageDestinationRef
  • Переход кода аудиоустройства в ARC
  • Нужен ли мне метод dealloc с ARC?
  • AVPlayer продолжает воспроизводиться после удаления ViewController из NavigationController
  • Как освободить частную собственность в iOS 7 с помощью ARC
  • Как лучше сохранить себя для делегата с ARC?
  • ios - Проблемы с парсером в NSObjCRuntime, NSZone и NSObject
  • Управление памятью в приложении iOS на основе карты
  • Безопасно ли присваивать свойство результат инициализации с автореализацией при использовании ARC?
  • Давайте будем гением компьютера.