六.对象相等性判断和NSCopying协议

1.对象等同性
NSObject 协议判断等同性的两个方法(当且仅当支持值完全相同,两个对象才完全相等)
@protocol NSObject

  • (BOOL)isEqual:(id)object;

@property (readonly) NSUInteger hash; //(对象相等hash值相等,反之不一定;hash一般用作哈希码索引,用在Array,Dictionary,Set集合中)
1.1一般自定义对象判断相等都只要判定属性值是否相等,改写如上两个方法就可以实现

//所有属性相同两个对象就相同(ps:如果该对象是数据库里面创建的对象,我们只要判断主键是否相等即可)
- (BOOL)isEqual:(id)aObject
{
    if(self == aObject) return YES;
    if ([self class] != [aObject class]) return NO;

    HsCodeInfo *codeInfo = (HsCodeInfo*)aObject;
    return ([_code isEqualToString:[codeInfo getCode]] && _codeType == [codeInfo getCodeType]);
}
//如下方法构建hash值就可以保存唯一
- (NSUInteger)hash
{
    NSString *hashStr = [NSString stringWithFormat: @"%d-%@", _codeType, _code];
    return [hashStr hash];
}

1.2另外如果要更加美观,提交监测速度,可以类推isEqualToString方法构建一个,修改isEqual方法

//省去类型判断
- (BOOL)isEqualToCodeInfo:(HsCodeInfo*)codeInfo
{
    if(self == codeInfo) return YES;

    return ([_code isEqualToString:[codeInfo getCode]] && _codeType == [codeInfo getCodeType]);
}

//同时修改如下方法
- (BOOL)isEqual:(id)object
{
    if ([self class] == [object class]){
        return [self isEqualToCodeInfo:(HsCodeInfo*)object];
    }else{
        return [super isEqual:object];
    }
}

1.3尽量不要把可变对象放入集合后,又再次修改可变对象。(可能会导致set集合里面保护重复对象)

- (void)testDuplicateSet
{
    NSMutableSet *set = [NSMutableSet new];
    NSMutableArray *classIdArr1 = [@[@10042,@10043] mutableCopy];
    [set addObject:classIdArr1];//set = {((10042,10043))}
    NSMutableArray *classIdArr2 = [@[@10042] mutableCopy];
    [set addObject:classIdArr2];//set = {((10042),(10042,10043))}
    [classIdArr2 addObject:@10043];//有重复对象了  set = {((10042,10043),(10042,10043))}

    //如何修复
    NSSet *set2 = [set copy]; //恢复正常 set2 = {((10042,10043))}
}

2.如果自定义的类要实现copy方法(其实调用的是copyWithZone),就要实现NSCopying协议

  • (id)copyWithZone:(nullableNSZone *)zone;(zone参数不用考虑现在都不用了)
//  HsCodeInfo.h
@interface HsCodeInfo : NSObject
{
    short  _codeType;
    NSString *_code;
}
@end
//  HsCodeInfo.m
#import "HsCodeInfo.h"
@implementation HsCodeInfo
-(id)initWithCode:(NSString*)stockcode AndType:(short)type
{
    self = [super init];
    if (self) {
        _code = [(stockcode==nil?@"":stockcode) copy];
        _codeType = type;
    }
    return self;
}
-(id)copyWithZone:(NSZone *)zone
{
    HsCodeInfo *codeInfo = [[HsCodeInfo allocWithZone:zone]initWithCode:_code AndType:_codeType];
    //如有需要这里还可以做其他数据结构的拷贝,如集合。不过要考虑清楚这里添加了,每次调用copy都会调用,如果是比较复杂的结构,建议还是新建一个接口
    return codeInfo;
}
@end

2.1copy和mutableCopy 一般调用关系如下所示
(可变对象通过不可变对象mutableCopy获取)
-[ NSArraymutableCopy] => NSMutableArray

NSMutableArray *classIdArr2 = [@[@10042] mutableCopy];

(不可变对象通过可变对象copy获取)
-[ NSMutableArraycopy] => NSArray

NSMutableArray *mutableArr = [NSMutableArray arrayWithObjects:@1,@2, nil];
NSArray *immutableArr = [mutableArr copy];

如果你发现本文对你有所帮助,如果你认为其他人也可能受益,请把它分享出去。

你可能感兴趣的:(六.对象相等性判断和NSCopying协议)