iOS使用containsObject的那些坑

        

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


        基于以上的需求,很容易想到使用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;

<pre name="code" class="objc" style="font-size: 13.3333px;">@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方法就能完美实现我们想要的功能。那么问题来了,像以下代码,会存在什么问题?
<span style="font-size: 13.3333px;">NSMutableArrray *personArray = [[NSMutableArray alloc] init] ;
...
</span>
<span style="font-size: 13.3333px;">在某个controller中初始化了数组,该controller注册了某个通知,有其他类每隔一定时间发送通知给controller,通知里包含person对象。当前controller收到通知后,通过containObject方法过滤重复的person,然后保存到personArray 中。
通知的处理函数如下:
</span>
-(void)didReceiveNotification:(id)sender
{
      ...
      Person *newPerson = [[sender userInfo] objectFor:@"person" ];//此处取出通知中的person对象
     ...(做一些其他运算)
      if(![personArray containsObject:newPerson ])
      {
            [personArray addObject:newPerson];
      }
}

       之后大家猜想,假设personArray保存了多个person,那么这些person的是不是能达到预期,name和age都不同,大家猜猜看?

如果您对我的文章感兴趣,请关注我的公众号"充电实践",希望在互联网的道路上我们并肩前行。


  • 5
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

充电实践

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值