ios - 使用NSArray containObject:方法比较对象
PHP中文网
PHP中文网 2017-04-17 17:13:12
[iOS讨论组]
PHP中文网
PHP中文网

认证高级PHP讲师

全部回复(6)
PHPz

关于那两个问题

问题一

原题主的代码是这样的:

NSArray *collection = [[NSArray alloc] initWithObjects:A, B, C, nil]; //A, B, C are custom "Item" objects
Item *tempItem = [[Item alloc] initWithLength:1 width:2 height:3];  
//3 instance variables in "Item" objects
if([collection containsObject:tempItem]) {
    NSLog(@"collection contains this item");
}

方法一:

you will either need to send [collection containsObject:] an instance of a variable it contains (e.g. A, B, or C)
向[collection containsObject:]传collection中包含的实例变量,比如[collection containObject:A]。

感觉这应该是可以的,毕竟如果就是A, B, C本身的话在内存空间的地址应该是一样的。但是这么做的话觉得这代码也没什么意思了,我用A, B, C初始化了一个collection,然后我又来判断A, B, C是不是在这个collection里面==

方法二:

you will need to override the [NSObject isEqual:] method in your Fruit class.

这应该是正解,详见补充3。

问题二

补充3里面NSHipster的文章里面有详细讲到,下面都是节选翻译自动脑补的。

继承自NSObject的子类要Override这个isEqual:方法要做以下几件事:

  • Implement a new isEqualTo__ClassName__: method, which performs the meaningful value comparison.
  • Override isEqual: to make class and object identity checks, falling
    back on the aforementioned value comparison method.
  • Override hash

如果是自己定义的子类:

@interface Person
@property NSString *name;
@property NSDate *birthday;

- (BOOL)isEqualToPerson:(Person *)person;
@end

@implementation Person

- (BOOL)isEqualToPerson:(Person *)person {
  if (!person) {
    return NO;
  }

  BOOL haveEqualNames = (!self.name && !person.name) || [self.name isEqualToString:person.name];
  BOOL haveEqualBirthdays = (!self.birthday && !person.birthday) || [self.birthday isEqualToDate:person.birthday];

  return haveEqualNames && haveEqualBirthdays;
}

#pragma mark - NSObject

- (BOOL)isEqual:(id)object {
  if (self == object) {
    return YES;
  }

  if (![object isKindOfClass:[Person class]]) {
    return NO;
  }

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

- (NSUInteger)hash {
  return [self.name hash] ^ [self.birthday hash];
}

最后,重载hash的时候还有一个trick,即用到了XOR,大叔是这么说的,

In reality, a simple XOR over the hash values of critical properties is sufficient 99% of the time.

嗯,就是对性能优化什么的有好处啦,关于这个他推荐了这篇文章。

关于po主的真正Bug

使用stringWithUTF8String:造成比较错误,因为它会在str末尾会包含"\n"。
改成stringWithFormat:的方法即可。
详见补充2.

补充

话说真不是故意自问自答的(答题时间可以证明po主的清白!╮(╯▽╰)╭)

迷茫

你传过去的参数类型对吗?

高洛峰

楼主,判断iseuqal不是判断指针和地址,是看hash值是不是相同

黄舟

建议楼主去写一篇文章好了。。竟然自问自答 =͟͟͞͞( •̀д•́)

迷茫

我以为是提问回答环节,没想到题主 自我解决了问题.还非常详细!非常好!赞一下

大家讲道理

containObject比较字符串,实际是看字符串的hash,相同的字符串虽然对象存储地址不同,但hash相同,所以可以直接查找

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号