[英]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. NSDictionary
与CFDictionaryRef
是免费的桥接,但是在添加对象时它们实际上在行为上有所不同。 Specifically, NSDictionary
's -setObject:forKey:
will copy the key, but CFDictionaryRef
's CFDictionarySetValue()
will not copy the key. 具体来说,
NSDictionary
的-setObject:forKey:
将复制密钥,但CFDictionaryRef
的CFDictionarySetValue()
将不复制密钥。 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.