简体   繁体   English

如何在Objective-C中使用对象作为键

[英]How to use an object as a key in Objective-C

I would like to use a custom object as a key in a hash-like structure. 我想将自定义对象用作类似哈希的结构中的键。 I've tried using NS[Mutable]Dictionary but in order for my object to be a key it has to implement the NSCopying protocol. 我尝试使用NS[Mutable]Dictionary但是为了使我的对象成为键,它必须实现NSCopying协议。 NSDictionary is sending a copy message to all of it's keys as far as I've read. 据我所读, NSDictionary正在向其所有键发送copy消息。 I don't want to implement the protocol (my object is quite complex) nor do I want it to be copied. 我不想实现协议(我的对象很复杂),也不想复制它。 What are my options? 我有什么选择? Do I have any? 我有吗

NSDictionary is toll-free bridged with CFDictionaryRef , but they actually differ in behavior when adding objects. NSDictionaryCFDictionaryRef是免费的桥接,但是在添加对象时它们实际上在行为上有所不同。 Specifically, NSDictionary 's -setObject:forKey: will copy the key, but CFDictionaryRef 's CFDictionarySetValue() will not copy the key. 具体来说, NSDictionary-setObject:forKey:将复制密钥,但CFDictionaryRefCFDictionarySetValue()复制密钥。 This means that if you want to use non-copyable keys, you can use CFDictionarySetValue() instead to add it to the dictionary. 这意味着,如果要使用不可复制的键,则可以使用CFDictionarySetValue()代替将其添加到字典中。

CFDictionarySetValue((CFMutableDictionaryRef)myDict, myKey, myValue);

This will still retain the key, but it won't copy it. 这仍将保留密钥,但不会复制它。 And you can use the normal NSDictionary methods for everything else. 您可以对其他所有内容使用常规的NSDictionary方法。

Do you need the NSDictionary to retain the object? 您是否需要NSDictionary来保留对象? If not, you can turn it into an NSValue and use that as the key: 如果没有,您可以将其转换为NSValue并将其用作键:

NSValue *value = [NSValue valueWithNonretainedObject:yourCustomObject];
[dictionary setObject:someObject forKey:value];

This can get a bit messy but is in alternative to implementing NSCopying . 这可能会有点混乱,但是可以替代实现NSCopying

You can roll your own dictionary. 您可以滚动自己的字典。 Not really that hard. 并不那么难。

Another option is to use a surrogate object, containing a pointer to "the" object. 另一种选择是使用代理对象,其中包含指向“ the”对象的指针。 The surrogate would implement the hash and either copy or reference the fields to be compared for isEqual. 代理将实现哈希,并复制或引用要比较isEqual的字段。 It could do a basic sanity check to assure the compared fields have not been changed when it's referenced. 它可以进行基本的健全性检查,以确保在引用时比较的字段没有被更改。

You could just do this: 您可以这样做:

- (id)copyWithZone:(NSZone *)zone {
    return [self retain];
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM