美文网首页iOS开发代码段iOS开发iOS 开发
iOS-两个NSIndexPath对象的正确比较方式

iOS-两个NSIndexPath对象的正确比较方式

作者: icetime17 | 来源:发表于2016-03-22 09:00 被阅读1792次

在UITableView和UICollectionView中, 经常会遇到比较两个NSIndexPath对象是否相同的情况.

错误写法

if (currentIndexPath != lastIndexPath) {
    // TODO
} else {
    // TODO
}

因两个NSIndexPath对象分别指向不同的内存区域, 所以一般情况下, 以上的比较方式会永远成立.

分别使用section和row/item

只能分别对NSIndexPath对象的section与row或item进行判断:
对于UITableView:

if (currentIndexPath.section != lastIndexPath.section ||
    currentIndexPath.row != lastIndexPath.row) {
    // TODO
} else {
    // TODO
}

而对于UICollectionView:

if (currentIndexPath.section != lastIndexPath.section ||
    currentIndexPath.item != lastIndexPath.item) {
    // TODO
} else {
    // TODO
}

使用NSObject的isEqual:方法

使用section和row/item的方式比较麻烦.
其实NSIndexPath对象可以通过NSObject的isEqual:方法来进行比较, 实际上比较的是二者的hash值.
因此跟二者的内存地址无关.

if (![currentIndexPath isEqual:lastIndexPath]) {
    // TODO
}

至于hash值, 涉及到NSObject的更深层次的内容, 暂时还不是很清楚, 只是做了些简单的测试.

(lldb) po currentIndexPath
<NSIndexPath: 0x16ee8890> {length = 2, path = 0 - 0}

(lldb) po lastIndexPath
<NSIndexPath: 0x16d74470> {length = 2, path = 0 - 0}

(lldb) p currentIndexPath==lastIndexPath
(bool) $3 = false
(lldb) p currentIndexPath!=lastIndexPath
(bool) $4 = true
(lldb) p [currentIndexPath isEqual:lastIndexPath]
(BOOL) $5 = YES
(lldb) p [currentIndexPath compare:lastIndexPath]
(NSComparisonResult) $6 = 0
(lldb) p currentIndexPath.hash
(NSUInteger) $7 = 22
(lldb) p lastIndexPath.hash
(NSUInteger) $8 = 22

两个NSIndexPath对象的hash值相等, 因此isEqual:的结果为YES.
同样, 对应NSString, NSArray, NSDictionary等对象, 除了各自的isEqualToString, isEqualToArray, isEqualToDictionary之外,
还可以使用isEqual:进行比较, 同样比较的是其hash值.

使用NSIndexPath的compare:方法

另外, 还可以使用NSIndexPath的compare:方法,

if ([currentIndexPath compare:lastIndexPath] != NSOrderedSame) {
    // TODO
}

使用compare:比较的结果有三种: NSOrderedAscending, NSOrderedSame和NSOrderedDescending.

Demo

Demo地址:DemoNSObjectRelatedAll

相关文章

网友评论

  • 飞翔的小骑兵:isequal 不就行了么。。。。。 :flushed:
    icetime17:再次验证了一下哦,compare是可以的呢。
    之前比较low的比较方式是这样的:
    if (indexPath.section != lastIndex.section || indexPath.item != lastIndex.item) {
    // The different indexPath
    } else {
    // The same indexPath
    }
    现在,其实可以使用isEqual和compare另外两种比较方式,
    if (![indexPath isEqual:lastIndex])

    if ([indexPath compare:lastIndex] != NSOrderedSame)
    这两种比较方式应该是跟NSObject的hash值相关的。

    下边是调试时候的log:
    (lldb) po indexPath
    <NSIndexPath: 0x16ee8890> {length = 2, path = 0 - 0}

    (lldb) po lastIndex
    <NSIndexPath: 0x16d74470> {length = 2, path = 0 - 0}

    (lldb) p indexPath==lastIndex
    (bool) $3 = false
    (lldb) p indexPath!=lastIndex
    (bool) $4 = true
    (lldb) p [indexPath isEqual:lastIndex]
    (BOOL) $5 = YES
    (lldb) p [indexPath compare:lastIndex]
    (NSComparisonResult) $6 = 0
    (lldb) p indexPath.hash
    (NSUInteger) $7 = 22
    (lldb) p lastIndex.hash
    (NSUInteger) $8 = 22
    飞翔的小骑兵:@icetime17 compare 其实是有问题的。 :smile:
    icetime17:@c1ear 谢谢提醒。其实主要还是看使用场景,我遇到的情况是将之前的indexpath存到另一个变量中,然后后来点击cell时判断是不是之前存的那个indexpath,所以使用section和row的方式来判断。试过isequal了,还有compare方法,在我这里结果是可行的。但不清楚是不是跟section和row结合的方法原理完全一致呢?

本文标题:iOS-两个NSIndexPath对象的正确比较方式

本文链接:https://www.haomeiwen.com/subject/kltllttx.html