iOS使用containsObject容易犯的错误

电子说

1.3w人已加入

描述

项目开发过程中可能会有这种需求,某个可变数组不断地增加元素,同时我们需要判断新的元素是否已经在数组里,如果不在才添加该元素,否则丢弃。

基于以上的需求,很容易想到使用NSArray的containsObject方法。我们先来看看官方的介绍:

- (BOOL)containsObject:(ObjectType)anObject

Parameters

anObject

An object.

Return Value

YES if anObject is present in the array, otherwise NO.

Discussion

Starting at index 0, each element of the array is passed as an argument to an isEqual: message sent to anObject until a match is found or the end of the array is reached. Objects are considered equal if isEqual: (declared in the NSObject protocol) returns YES.

对于普通的NSObject比较用isEqual:方法比较hash,而对于对于自己定义的类,直接使用containsObject会一直返回NO,原因是containsObject比较的是数组里的两个对象,其hash值必然不一样。比如以下自定义类:

@interface Person

@property NSString *name;

@property NSInteger age;

@end

@implementation Person

@end

Person中包含name和age,分别表示名字和年龄,数组中包含多个Person,我们的目的是,如果数组中存在同样的人名,并且年龄完全相同,就舍弃新的Person,如何实现这个需求呢?我们需要重载isEqual方法

- (BOOL)isEqualToPerson:(Person *)person {

if (!person) {

return NO;

}

BOOL bIsEqualNames = (!self.name && !person.name) || [self.name isEqualToString:person.name];

BOOL bIsEqualAges = self.age == person.age;

return bIsEqualNames && bIsEqualAges;

}

#pragma mark - 重载isEqual方法

- (BOOL)isEqual:(id)object {

if (self == object) {

return YES;

}

if (![object isKindOfClass:[Person class]]) {

return NO;

}

return [self isEqualToPerson:(Person *)object];

}

通过重载后,containsObject方法就能完美实现我们想要的功能。那么问题来了,像以下代码,会存在什么问题?

NSMutableArrray *personArray = [[NSMutableArray alloc] init] ;

...

在某个controller中初始化了数组,该controller注册了某个通知,有其他类每隔一定时间发送通知给controller,通知里包含person对象。当前controller收到通知后,通过containObject方法过滤重复的person,然后保存到personArray 中。

通知的处理函数如下:

-(void)didReceiveNotification:(id)sender

{

...

Person *newPerson = [[sender userInfo] objectFor:@"person" ];//此处取出通知中的person对象

...(做一些其他运算)

if(![personArray containsObject:newPerson ])

{

[personArray addObject:newPerson];

}

}
编辑:hfy

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分