7

There are a couple good examples on SO about CFUUID, notably this one:

How to create a GUID/UUID using the iPhone SDK

But it was made for pre-ARC code, and I'm not a CF junkie (yet), so can someone provide example code that works with ARC?

+ (NSString *)GetUUID
{
  CFUUIDRef theUUID = CFUUIDCreate(NULL);
  CFStringRef string = CFUUIDCreateString(NULL, theUUID);
  CFRelease(theUUID);
  return [(NSString *)string autorelease];
}
Community
  • 1
  • 1
TigerCoding
  • 8,710
  • 10
  • 47
  • 72

3 Answers3

23

You want a "bridged transfer":

+ (NSString *)GetUUID
{
  CFUUIDRef theUUID = CFUUIDCreate(NULL);
  CFStringRef string = CFUUIDCreateString(NULL, theUUID);
  CFRelease(theUUID);
  return (__bridge_transfer NSString *)string;
}

The Transitioning to ARC Guide says

__bridge_transfer or CFBridgingRelease() moves a non-Objective-C pointer to Objective-C and also transfers ownership to ARC.

However! You should also rename your method. ARC uses method name conventions to reason about retain counts, and methods that start with get in Cocoa have a specific meaning involving passing a buffer in for it to get filled with data. A better name would be buildUUID or another word that describes the use of the UUID: pizzaUUID or bearUUID.

jscs
  • 63,694
  • 13
  • 151
  • 195
  • Thanks Jacques, I thought it was __bridge but wasn't certain. I'm still not sure how the retain cycles work with CF, but I'll get to it one of these days. – TigerCoding May 07 '12 at 03:38
  • A quick string search through the link you provided shows we can't use the word "new" but I didn't see anything about using the word "get." Did you confuse the two or did I miss something? – TigerCoding May 07 '12 at 03:42
  • I admit that I'm not 100% certain that `get` causes problems with ARC (I've been meaning to look into it), but that is a very long-standing naming convention in Cocoa. See `-[NSArray getObjects:range:]`, `-[NSString getCharacters:range:]`, and others. – jscs May 07 '12 at 03:45
  • For the purposes of Objective-C naming conventions, I doubt get and Get are equivalent. But like Jacques, I'd suggest renaming the method. Just `UUID` would be a fine name. – Steven Fisher May 09 '12 at 00:41
  • See my answer for a more updated version of this which uses a built-in function and only one line of code: http://stackoverflow.com/a/22839680/1091402 – Rick Jul 25 '14 at 12:44
  • Why don't you have to `CFRelease(string);`? – Ky - Apr 22 '16 at 16:54
  • Because you don't want to _just_ release it, @BenC.R.Leggiero, you want ARC to take ownership. The name `CFBridgingRelease()` makes this clear, and, as the doc quote I included says, it's equivalent to `__bridge_transfer`. – jscs Apr 22 '16 at 16:58
5

Assuming you no longer need to support iOS prior to 6.0 at this point, you can skip all the Core Foundation UUID stuff and just do this to get a fresh one:

NSString * uuidStr = [[NSUUID UUID] UUIDString];
Ben Zotto
  • 70,108
  • 23
  • 141
  • 204
0

One-liner:

NSString *UUID = CFBridgingRelease(CFUUIDCreateString(kCFAllocatorDefault, CFUUIDCreate(NULL)));
maz
  • 8,056
  • 4
  • 26
  • 25
Rick
  • 3,240
  • 2
  • 29
  • 53
  • This requires you to already have a `CFUUIDRef`, which is not the case in the OP's code. – jscs Jul 25 '14 at 17:09