如何在ARC下创建不会泄漏内存的CFUUID NSString?

7

关于CFUUID,SO上有一些很好的例子,特别是这个:

如何使用iPhone SDK创建GUID / UUID

但它是为预先ARC代码设计的,而且我不是一个CF爱好者(至少不是现在),所以可以有人提供与ARC兼容的示例代码吗?

+ (NSString *)GetUUID
{
  CFUUIDRef theUUID = CFUUIDCreate(NULL);
  CFStringRef string = CFUUIDCreateString(NULL, theUUID);
  CFRelease(theUUID);
  return [(NSString *)string autorelease];
}
3个回答

23
您想要进行“桥接转移”:
+ (NSString *)GetUUID
{
  CFUUIDRef theUUID = CFUUIDCreate(NULL);
  CFStringRef string = CFUUIDCreateString(NULL, theUUID);
  CFRelease(theUUID);
  return (__bridge_transfer NSString *)string;
}

转换为ARC指南说:

__bridge_transferCFBridgingRelease()将非Objective-C指针移动到Objective-C,并转移所有权到ARC。

但是!您还应该重命名方法。 ARC使用方法名称约定来推断保留计数,以Cocoa中以get开头的方法具有涉及传递缓冲区以获取填充数据的特定含义。更好的名称可能是buildUUID或另一个描述UUID用法的单词:pizzaUUIDbearUUID


谢谢Jacques,我以为是__bridge,但不确定。我仍然不确定CF如何工作,但总有一天我会弄清楚的。 - TigerCoding
通过您提供的链接进行快速字符串搜索,我们发现不能使用单词“new”,但我没有看到关于使用单词“get”的任何内容。您是混淆了这两个单词还是我错过了什么? - TigerCoding
我承认我不确定get是否会在ARC中引起问题(我一直想研究一下),但这是Cocoa中一个非常长期存在的命名约定。例如-[NSArray getObjects:range:]-[NSString getCharacters:range:]等。 - jscs
为什么您不需要 CFRelease(string); - Ky -
因为您不仅想要发布它, @BenC.R.Leggiero,而是想让 ARC 接管。名称 CFBridgingRelease() 可以清楚地表明这一点,并且正如我所说的文档引用,它等效于 __bridge_transfer - jscs
显示剩余2条评论

5

假设您现在不再需要支持6.0之前的iOS版本,您可以跳过所有Core Foundation UUID相关的内容,只需执行以下操作即可获得新的UUID:

NSString * uuidStr = [[NSUUID UUID] UUIDString];

后来我在其他应用程序中使用了它。忘记了这篇文章。 - TigerCoding
这会返回一个格式与CFUUIDCreateString完全相同的字符串吗? - Ky -
1
@BenC.R.Leggiero 是的。UUID 的文本格式是标准的。 - Ben Zotto

0

一行代码:

NSString *UUID = CFBridgingRelease(CFUUIDCreateString(kCFAllocatorDefault, CFUUIDCreate(NULL)));

这要求您已经拥有一个CFUUIDRef,而这在OP的代码中并不是这种情况。 - jscs

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接