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?
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.
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.
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.