2012-07-20 84 views
2

我有一堆设备。 他们每个人都有一个UUID区分他们彼此。从逻辑上讲,这是自然的事情,然后在字典中跟踪他们。使用CFUUIDRefs作为字典的键

但是,[device UUID]方法会传回一个CFUUIDRef。

首先,这不是一个对象。但是,嘿,我们可以解决这个问题。 [device_dictionary setObject:key(__ bridge id)[device uuid]]的设备;

不,等待,这不是一个有效的密钥:它不实施<NSCopying>协议。

更重要的是,由于我正在将这些CFUUIDRefs强制转换为对象,字典甚至会在它传递两次相同的CFUUIDRef时意识到这一点吗?或者,由演员在飞行中创建的新对象是否不会注册为同一个对象?

小心帮我头脑风暴呢?如果您将UUID作为非对象提供,您将如何使用UUID键入字典?

回答

3

显而易见的解决方案是将返回的CFUUIDRef转换为字符串作为字典中的键。

您可以转换CFUUIDRefCFStringRef使用CFUUIDCreateString()如下:

CFStringRef uuidString = CFUUIDCreateString(kCFAllocatorDefault, [device uuid]); 

然后,您可以使用免费桥接至CFStringRef转换为NSString用在NSDictionary

如果需要的UUID的字符串表示转换回CFUUIDRef你可以使用CFUUIDCreateFromString()如下:

CFUUIDRef uuid = CFUUIDCreateFromString(kCFAllocatorDefault, uuidString); 

还为CFUUIDRef的包装,它实现NSCoding可在https://gist.github.com/294023找到。但是,这看起来不兼容ARC。

1

CFUUIDRefCFType,你可以使用任何CFType作为键在CFDictionary

CFMutableDictionaryRef d = CFDictionaryCreateMutable(
    kCFAllocatorDefault, 
    0, 
    &kCFTypeDictionaryKeyCallBacks, 
    &kCFTypeDictionaryValueCallBacks); 

CFUUIDRef u1 = CFUUIDCreateFromString(kCFAllocatorDefault, CFSTR("68753A44-4D6F-1226-9C60-0050E4C00067")); 
CFUUIDRef u2 = CFUUIDCreateFromString(kCFAllocatorDefault, CFSTR("68753A44-4D6F-1226-9C60-0050E4C00067")); 

CFDictionarySetValue(d, u1, CFSTR("fnord")); 

CFShow(CFDictionaryGetValue(d, u2)); // prints "fnord" 

不幸的是免费电话桥接不会在这种情况下正常工作,如-copy将在键调用在NSMutableDictionary-setObject:forKey:之前自定义回调(请参阅http://www.cocoabuilder.com/archive/cocoa/163407-using-nsimages-as-keys-to-dictionary.html#163439)导致崩溃。在任何情况下,使用CFDictionary代替NSDictionary是微不足道的。

另一种选择是NSMapTable如果你想要一个Objective-C的解决方案:

NSMapTable *t = NSCreateMapTable(NSObjectMapKeyCallBacks, NSObjectMapValueCallBacks, 0);  
NSMapInsert(t, u1, CFSTR("fnord")); 
NSLog(@"%@", NSMapGet(t, u2)); // prints "fnord"