博客
关于我
Objective-C——判断对象等同性
阅读量:797 次
发布时间:2023-02-17

本文共 2527 字,大约阅读时间需要 8 分钟。

OC对象等同性深入理解

在软件开发中,无论使用何种语言,比较两个对象是否相等都至关重要。OC也不例外。我们从最基本的 NSString 比较开始,逐步深入探讨对象等同性的实现原理。

NSString对象的比较

假设我们有以下代码:

NSString *str1 = [[NSString alloc] initWithCString:"equal" encoding:NSUTF8StringEncoding];NSString *str2 = @"equal";if (str1 == str2) {    NSLog(@"equal");}

这段代码看似简单,但运行结果却令人困惑。尽管 str1str2 表面上看起来相等,但由于比较的是对象指针的相等性,而不是实际的字符串内容,导致结果总是 false

正确的比较方法

为了正确比较两个字符串,我们应该使用 isEqual: 方法:

NSString *str1 = [[NSString alloc] initWithCString:"equal" encoding:NSUTF8StringEncoding];NSString *str2 = @"equal";if ([str1 isEqual:str2]) {    NSLog(@"equal");}

这里 isEqual: 方法在 NSString 类中被精细实现,真正比较的是字符串内容,而不是对象指针。因此,输出 "equal" 是正确的。

自定义对象的等同性实现

为了更深入理解,我们可以创建一个自定义类 EqualObject,并实现 isEqual: 方法。

@interface EqualObject : NSObject@property (nonatomic, strong) NSString *name;@end@implementation EqualObject@end

创建两个 EqualObject 实例并比较:

EqualObject *object1 = [EqualObject new];EqualObject *object2 = [EqualObject new];if ([object1 isEqual:object2]) {    NSLog(@"equal");}

此时,输出结果仍为 false,因为 isEqual: 方法的默认实现是比较对象指针是否相同。因此,我们需要自定义 isEqual: 方法:

-(BOOL)isEqual:(id)object {    if ([self class] == [object class]) {        if (![self.name isEqual:object.name]) {            return NO;        }        return YES;    } else {        return [super isEqual:object];    }}

这段代码首先检查对象的类别是否相同,然后比较 name 属性。如果 name 相同,返回 true,否则返回 false

定制等同性方法

为了更精确地控制等同性,我们可以为 EqualObject 类添加定制的 isEqualToEqualObject: 方法:

-(BOOL)isEqualToEqualObject:(EqualObject *)object {    if (self == object) {        return YES;    }    if (![self.name isEqualToString:object.name]) {        return NO;    }    return YES;}-(BOOL)isEqual:(id)object {    if ([self class] == [object class]) {        return [self isEqualToEqualObject:object];    } else {        return [super isEqual:object];    }}

客户端代码变为:

if ([object1 isEqualToEqualObject:object2]) {    NSLog(@"equal");}

这样可以更明确地比较对象的等同性。

对象Hash码

每个 OC 对象都有一个 hash 方法,用于计算对象的哈希值。集合(如 NSArrayNSSet 等)使用哈希值来存储对象,以提高存取效率。

-(NSUInteger)hash {    NSUInteger nameHash = [_name hash];    return nameHash;}

如果对象的 hash 值相同,但对象内容不同,可能导致潜在的冲突。为了避免这种情况,我们可以自定义 hash 方法:

-(NSUInteger)hash {    NSUInteger nameHash = [_name hash];    NSUInteger ageHash = _age;    return nameHash ^ ageHash;}

集合的等同性比较

对于 NSArrayisEqual: 方法默认比较每个元素的位置:

NSArray *array1 = @[object1, object2];NSArray *array2 = @[object1, object2];if ([array1 isEqual:array2]) {    NSLog(@"equal");}

如果数组中的元素位置相同且每个元素相等,数组才被认为相等。

注意事项

在使用集合(如 NSSet)时,需注意其 isEqual:hash 方法的行为。为了避免冲突,应确保所有对象的 hash 值和内容都唯一。

通过以上方法,我们可以更好地理解和实现对象等同性的原理,从而在实际开发中更高效地管理对象比较和存储。

转载地址:http://gynfk.baihongyu.com/

你可能感兴趣的文章
Nest.js 6.0.0 正式版发布,基于 TypeScript 的 Node.js 框架
查看>>
Netpas:不一样的SD-WAN+ 保障网络通讯品质
查看>>
Netty WebSocket客户端
查看>>
Netty工作笔记0011---Channel应用案例2
查看>>
Netty工作笔记0014---Buffer类型化和只读
查看>>
Netty工作笔记0050---Netty核心模块1
查看>>
Netty工作笔记0084---通过自定义协议解决粘包拆包问题2
查看>>
Netty常见组件二
查看>>
netty底层源码探究:启动流程;EventLoop中的selector、线程、任务队列;监听处理accept、read事件流程;
查看>>
Netty核心模块组件
查看>>
Netty框架的服务端开发中创建EventLoopGroup对象时线程数量源码解析
查看>>
Netty源码—2.Reactor线程模型一
查看>>
Netty源码—4.客户端接入流程一
查看>>
Netty源码—4.客户端接入流程二
查看>>
Netty源码—5.Pipeline和Handler一
查看>>
Netty源码—6.ByteBuf原理二
查看>>
Netty源码—7.ByteBuf原理三
查看>>
Netty源码—7.ByteBuf原理四
查看>>
Netty源码—8.编解码原理二
查看>>
Netty源码解读
查看>>