71
votes

I need to generate a UUID string in some code with ARC enabled.

After doing some research, this is what I came up with:

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

Am I correctly using __bridge_transfer to avoid leaking any objects under ARC?

3

3 Answers

103
votes

Looks fine to me. This is what I use (available as a gist)

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

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

    return uuidString;
}

Edited to add

If you are on OS X 10.8 or iOS 6 you can use the new NSUUID class to generate a string UUID, without having to go to Core Foundation:

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

But mostly, if you just want to generate a unique string for a file or directory name then you can use NSProcessInfo's globallyUniqueString method like:

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

It's not a formal UUID, but it is unique for your network and your process and is a good choice for a lot of cases.

42
votes

That looks correct to me.

You have CFRelease'd uuid, which is your responsibility from the CFUUIDCreate()

And you've transferred ownership of the string to ARC, so the compiler knows to release uuidStr at the appropriate time.

7
votes

From clang docs:

(__bridge_transfer T) op casts the operand, which must have non-retainable pointer type, to the destination type, which must be a retainable object pointer type. ARC will release the value at the end of the enclosing full-expression, subject to the usual optimizations on local values.

So you are doing it right.