博客
关于我
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/

你可能感兴趣的文章
nginx 后端获取真实ip
查看>>
Nginx 学习总结(17)—— 8 个免费开源 Nginx 管理系统,轻松管理 Nginx 站点配置
查看>>
nginx 常用配置记录
查看>>
Nginx 我们必须知道的那些事
查看>>
Nginx 的 proxy_pass 使用简介
查看>>
Nginx 的配置文件中的 keepalive 介绍
查看>>
nginx 配置 单页面应用的解决方案
查看>>
nginx 配置~~~本身就是一个静态资源的服务器
查看>>
Nginx下配置codeigniter框架方法
查看>>
nginx添加模块与https支持
查看>>
Nginx的Rewrite正则表达式,匹配非某单词
查看>>
Nginx的使用总结(一)
查看>>
Nginx的是什么?干什么用的?
查看>>
Nginx访问控制_登陆权限的控制(http_auth_basic_module)
查看>>
nginx负载均衡的五种算法
查看>>
Nginx配置ssl实现https
查看>>
Nginx配置TCP代理指南
查看>>
Nio ByteBuffer组件读写指针切换原理与常用方法
查看>>
NI笔试——大数加法
查看>>
NLP 基于kashgari和BERT实现中文命名实体识别(NER)
查看>>