iOS - 두 NSIndexPath 객체의 올바른 비교 방법

2203 단어
UItableView와 UICollectionView에서는 두 NSIndexPath 대상이 같은지 비교하는 경우가 종종 있습니다.

잘못 쓰다

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

두 개의 NSIndexPath 대상이 각각 다른 메모리 영역을 가리키기 때문에 일반적인 상황에서 이상의 비교 방식은 영원히 성립될 것이다.

섹션과 row/item을 각각 사용합니다


NSIndexPath 객체의 섹션과 row 또는 item에 대해서만 판단할 수 있습니다: UItable View:
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:방법


섹션과row/item을 사용하는 방식은 비교적 번거롭다.사실 NSIndexPath 대상은 NSObject의 isEqual: 방법을 통해 비교할 수 있는데 실제적으로 비교한 것은 양자의hash값이다.따라서 양자의 메모리 주소와는 무관하다.
if (![currentIndexPath isEqual:lastIndexPath]) {
    // TODO
}

hash값에 대해 NSObject의 더 깊은 차원과 관련된 내용은 아직 잘 모르겠지만 간단한 테스트를 했을 뿐입니다.
(lldb) po currentIndexPath
 {length = 2, path = 0 - 0}

(lldb) po lastIndexPath
 {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 등 대상에 대응하여 각자의 isEqual ToString, isEqual ToArray, isEqual ToDictionary를 제외하고 isEqual: 비교를 할 수 있다. 똑같이 비교한 것은 그hash값이다.

NSIndexPath의 compare:메서드 사용


또한 NSIndexPath의 compare: 메서드를 사용할 수 있습니다.
if ([currentIndexPath compare:lastIndexPath] != NSOrderedSame) {
    // TODO
}

compare를 사용하여 비교한 결과는 세 가지가 있는데 그것이 바로 NSOrderedAscending, NSOrderedSame와 NSOrderedDescending이다.

Demo


Demo 주소: DemonSObjectRelatedAll

좋은 웹페이지 즐겨찾기