2010-11-17 104 views

回答

20

快速枚舉必須產生對象;由於NSIndexSet包含標量數字(NSUInteger),而不是對象,否,您無法快速枚舉索引集。

假設它可以將它們組裝成NSNumbers,但它不會很快。

+1

我不介意性能受到影響,但是在快速枚舉之前您必須慢速枚舉,對吧? – 2015-02-03 19:08:58

+1

使用帶標籤的指針(在OS X 10.7和iOS 5以後的64位平臺上),「NSIndexSet」快速枚舉應該非常快。 – 2016-06-23 03:44:18

22

while循環應該做的伎倆。在使用之前的索引之後,它會增加索引。

/*int (as commented, unreliable across different platforms)*/ 
NSUInteger currentIndex = [someIndexSet firstIndex]; 
while (currentIndex != NSNotFound) 
{ 
    //use the currentIndex 

    //increment 
    currentIndex = [someIndexSet indexGreaterThanIndex: currentIndex]; 
} 
+2

由於索引是無符號的,所以有效索引可以超出'int'表示的值的範圍。此外,如果定義了定位了「NS_BUILD_32_LIKE_64」的64位平臺或大樓,則索引是64位值。使用'NSUInteger'而不是'int'來匹配所有平臺下'NSIndexSet'存儲的類型。 – 2010-11-17 21:34:59

+2

@Jeremy W. Sherman:實際上,索引實際上限於那些可以由**正數** NSInteger表示的值,因爲「未找到」返回值是「NSNotFound」,它與「NSIntegerMax」相同 – JeremyP 2010-11-19 15:45:42

+1

@Evan:這個例子還是錯的。 while循環中的比較需要反對'NSNotFound' * not * -1。 – JeremyP 2010-11-19 15:46:35

142

在OS X 10.6+和iOS SDK 4.0+,你可以使用-enumerateIndexesUsingBlock:消息:

NSIndexSet *idxSet = ... 

[idxSet enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) { 
    //... do something with idx 
    // *stop = YES; to stop iteration early 
}]; 
+2

將NSInteger更改爲NSUInteger – cocoafan 2011-07-19 10:45:03

+3

這是正確的答案! – jaredsinclair 2012-12-04 05:36:27

+1

這是實際的答案,可以改變嗎? – Jameson 2014-08-20 21:50:35

10

簡短的回答:沒有。 NSIndexSet不符合<NSFastEnumeration> protocol

+0

enumerateIndexesUsingBlock:^(NSUInteger idx,BOOL * stop){} ---這是不是快速枚舉? – 2017-12-12 20:31:36

2

假設你有一個NSTableView實例(姑且稱之爲*tableView),可以從數據源(呃.. *myMutableArrayDataSource)刪除多個選定行,使用:

[myMutableArrayDataSource removeObjectsAtIndexes:[tableView selectedRowIndexes]]; 

[tableView selectedRowIndexes]返回NSIndexSet。 不需要自己開始枚舉NSIndexSet中的索引。

+0

這是一個關於'NSMutableArray'的真棒點,謝謝。 – 2015-02-03 18:54:10

+0

這實際上並沒有回答這個問題,而是說「也許你不需要提出這個問題開始,你想要這個快速列舉麼?」 – 2017-12-12 20:27:12