Создайте строку UUID с включенным ARC

Мне нужно сгенерировать строку UUID в некотором коде с включенным ARC.

Проведя некоторое исследование, это то, что я придумал:

CFUUIDRef uuid = CFUUIDCreate(NULL);
NSString *uuidStr = (__bridge_transfer NSString *)CFUUIDCreateString(NULL, uuid);
CFRelease(uuid);

Я правильно использую __bridge_transfer, чтобы избежать утечки каких-либо объектов в ARC?

Ответ 1

Выглядит хорошо. Это то, что я использую (доступно как gist)

- (NSString *)uuidString {
    // Returns a UUID

    CFUUIDRef uuid = CFUUIDCreate(kCFAllocatorDefault);
    NSString *uuidString = (__bridge_transfer NSString *)CFUUIDCreateString(kCFAllocatorDefault, uuid);
    CFRelease(uuid);

    return uuidString;
}

Отредактировано для добавления

Если вы находитесь на OS X 10.8 или iOS 6, вы можете использовать новый класс NSUUID для генерации строки UUID без необходимости обращаться к Core Foundation:

NSString *uuidString = [[NSUUID UUID] UUIDString];
// Generates: 7E60066C-C7F3-438A-95B1-DDE8634E1072

Но в основном, если вы просто хотите создать уникальную строку для имени файла или каталога, вы можете использовать метод NSProcessInfo globallyUniqueString, например:

NSString *uuidString = [[NSProcessInfo processInfo] globallyUniqueString];
// generates 56341C6E-35A7-4C97-9C5E-7AC79673EAB2-539-000001F95B327819

Это не формальный UUID, но он уникален для вашей сети и вашего процесса и является хорошим выбором для многих случаев.

Ответ 2

Это выглядит правильно для меня.

У вас есть CFRelease'd uuid, за что вы отвечаете за CFUUIDCreate()

И вы передали право собственности на строку на ARC, поэтому компилятор знает, чтобы освободить uuidStr в соответствующее время.

Ответ 3

Из clang docs:

(__bridge_transfer T) op задает операнд, который должен иметь не сохраняемый тип указателя, к типу назначения, который должен быть типом сохраняемого типа объекта. ARC выдает значение в конце охватывающего полного выражения с учетом обычных оптимизаций по локальным значениям.

Итак, вы делаете это правильно.