使用OC自定义了一个IntPair类作为NSDictionary类的键值,与JAVA中的Pair<int,int>使用方式类似,然而在使用过程中遇到了各种问题,有必要记录一下。
首先,需要实现NSCoping协议,如果不实现的话,在使用IntPair作为key向dictionary中添加数据时会报警告:Sending 'IntPair *__strong to parameter of incompatible type 'id<NSCopying> _Nonnull'
一开始没管,结果运行的时候,在setObject forKey函数这里直接崩溃,setObject forKey的声明如下:
- (void)setObject:(id)anObject forKey:(id <NSCopying>)aKey;
所以应该实现这个方法。
然后,实现了NSCopying协议后,发现key值不能比较是否相等,同样的key值被添加了多次,经过搜索知道,还需要重载NSObject的两个方法:
-(BOOL) isEqual:(id) object; -(NSUInteger) hash;
isEqual方法比较好理解,用于判断两个对象是否相等,比较好实现,
hash方法有必要说明一下,这个方法返回一个整数值作为哈稀表的表地址,熟悉哈稀算法的话就应该明白了,同一个键值的hash返回值也应该相同
下面是IntPair类的完整实现:
IntPair.h
#import <Foundation/Foundation.h> @interface IntPair : NSObject<NSCoding,NSCopying> @property(nonatomic,assign) int first; @property(nonatomic,assign) int second; -(IntPair *) initWithFirst:(int) first andSecond:(int) second; @end
IntPair.m
#import "IntPair.h" @implementation IntPair -(IntPair *) initWithFirst:(int)first andSecond:(int)second{ self.first = first; self.second = second; return self; } -(BOOL) isEqual:(id)object{ IntPair *pair = (IntPair *)object; if(pair != nil){ if(self.first == pair.first && self.second == pair.second){ return YES; } } return NO; } -(NSUInteger) hash{ return self.first * 1000 + self.second; } -(void) encodeWithCoder:(NSCoder *)aCoder{ NSNumber *first = [[NSNumber alloc] initWithInt:self.first]; NSNumber *second = [[NSNumber alloc] initWithInt:self.second]; [aCoder encodeObject:first forKey:@"first"]; [aCoder encodeObject:second forKey:@"second"]; } -(id) initWithCoder:(NSCoder *)aDecoder{ NSNumber *first = [aDecoder decodeObjectForKey:@"first"]; NSNumber *second = [aDecoder decodeObjectForKey:@"second"]; self.first = [first intValue]; self.second = [second intValue]; return self; } -(id) copyWithZone:(NSZone *)zone{ IntPair *pair = [[IntPair allocWithZone:zone] initWithFirst:self.first andSecond:self.second]; return pair; } @end