Objective-c:当键存在时,自定义类实例作为字典键返回nil

时间:2023-01-16 12:05:50

I have a custom class I'm using instances of as keys in a dictionary. The problem is, sometimes (not all the time) requesting a value from a dictionary with one of my custom instance keys returns nil when the key really is in the dictionary. I looked around the web on how to use custom objects as dictionary keys, and all I've been able to find is that you need to implement the NSCopying protocol, which I have done.

我有一个自定义类,我在字典中使用作为键的实例。问题是,有时(不是所有时候)请求字典中的值时,我的一个自定义实例键返回nil,而实际上该键在字典中。我在web上查看了如何使用自定义对象作为字典键,我所能找到的就是您需要实现NSCopying协议,我已经实现了。

My class looks like this:

我的班级看起来是这样的:

// .h
@interface MyObject: NSObject <NSCopying>

@property (copy) NSString* someString;
@property (copy) NSString* otherString;
@property int someInt;

+ (instancetype) objectWithString:(NSString*)str;
- (id) copyWithZone:(NSZone*)zone;
@end

// .m
@implementation MyObject

@synthesize someString;
@synthesize otherString;
@synthesize someInt;

+ (instancetype) objectWithString:(NSString*)str {
   id obj = [[self alloc] init];
   [obj setSomeString:str];
   [obj setOtherString:[str lowercaseString];
   [obj setSomeInt:0];
   return obj;
}

- (id) copyWithZone:(NSZone*)zone {
   id other = [[[self class] allocWithZone:zone] init];
   [other setSomeString:self.someString];
   [other setOtherString:self.otherString];
   [other setSomeInt:self.someInt];
   return other;
}
@end

Then I put some of these things in a mutable dictionary like this:

然后我把这些东西放进可变字典里,像这样

MyObject* key1 = [MyObject objectWithString:@"Foo"];
MyObject* key2 = [MyObject objectWithString:@"Bar"];
NSNumber* value1 = [NSNumber numberWithInt:123];
NSNumber* value2 = [NSNumber numberWithInt:456];

NSMutableDictionary* theDict = [[NSMutableDictionary alloc] init];
[theDict setObject:value1 forKey:key1];
[theDict setObject:value2 forKey:key2];

Now what I want to do is just pop a key/value pair out of the dictionary, so I do that like this:

现在我要做的就是从字典中取出一个键/值对,我这样做:

MyObject* theKey = [[theDict allKeys] firstObject];
NSNumber* theValue = [theDict objectForKey:theKey];

And here's where I run into problems. Most of the time, this works fine. However, sometimes objectForKey:theKey returns nil. I've put a breakpoint in my code and can confirm that theKey is indeed in the theDict.

这就是我遇到问题的地方。在大多数情况下,这是可行的。然而,有时objectForKey:theKey返回nil。我已经在代码中放入了一个断点,并可以确认密钥确实在theDict里面。

What am I doing wrong here?

我在这里做错了什么?

1 个解决方案

#1


5  

You should also implement -isEqual: and -hash on your custom objects.

您还应该在自定义对象上实现-isEqual:和-hash。

For more info: Apple Documentation, NSHipster article

更多信息:苹果文件,NSHipster文章

The reason you must do this is the keys can be copied when you put them in the dictionary and the default implementation of isEqual just does pointer comparison.

您必须这样做的原因是当您将键放入字典时可以复制它们,isEqual的默认实现只是做指针比较。

#1


5  

You should also implement -isEqual: and -hash on your custom objects.

您还应该在自定义对象上实现-isEqual:和-hash。

For more info: Apple Documentation, NSHipster article

更多信息:苹果文件,NSHipster文章

The reason you must do this is the keys can be copied when you put them in the dictionary and the default implementation of isEqual just does pointer comparison.

您必须这样做的原因是当您将键放入字典时可以复制它们,isEqual的默认实现只是做指针比较。