1、字典中的(有兩個方法):
//獲取所有key值
-(NSEnumerator<KeyType> *)keyEnumerator;
//獲取所有value值
-(NSEnumerator<ObjectType> *)objectEnumerator;
示例:
- (instancetype)initWithDictionary:(NSDictionary *)dic{
if (self = [super init]) {
NSEnumerator * enumeration = [dic keyEnumerator];
id key, value;
while (key = [enumeration nextObject]) {
value = [dic valueForKey:key];
[self setValue:value forKey:key];
}
}
return self;
}
經(jīng)過幾次測試,發(fā)現(xiàn)通過keyEnumerator,和objectEnumerator返回的數(shù)組都是與字典中的key和value的一一對應(yīng)的。雖然不明所以,但仍然可以這樣:
- (instancetype)initWithDictionary:(NSDictionary *)dic{
if (self = [super init]) {
NSEnumerator * key_enumeration = [dic keyEnumerator];
NSEnumerator * value_enumeration = [dic objectEnumerator];
id key, value;
while (key = [key_enumeration nextObject]) {
value = [value_enumeration nextObject];
[self setValue:value forKey:key];
}
}
return self;
}
二、數(shù)組中的(有兩個方法)
//正向遍歷數(shù)組 ——>完全可用 for in 語法代替
- (NSEnumerator<ObjectType> *)objectEnumerator;
//反向遍歷數(shù)組
- (NSEnumerator<ObjectType> *)reverseObjectEnumerator;
示例:
NSArray *array= [NSArray arrayWithObjects:
@"112",@"234",@"3434",@"3455" ,nil];
NSEnumerator *enumerator = [array reverseObjectEnumerator];
id thing;
while (thing = [enumerator nextObject]) {
NSLog(@"Ifound %@",thing);
}
//也可以這樣
NSArray *array= [NSArray arrayWithObjects:
@"112",@"234",@"3434",@"3455" ,nil];
NSEnumerator *enumerator = [array reverseObjectEnumerator];
NSArray *arr = [enumerator allObjects];
for (NSString *res in arr) {
NSLog(@"%@",res);
}
注意:
1、-(NSEnumerator *)objectEnumerator;
返回:一個枚舉器對象,可讓您訪問字典中的每個值。
注意:如果您將此方法與NSDictionary的可變子類的實例一起使用,則您的代碼不應(yīng)在枚舉過程中修改條目。 如果您打算修改條目,請使用allValues方法創(chuàng)建字典值的“快照”。 從這個快照中修改值。
2、- (ObjectType)nextObject;
枚舉集合中的下一個對象,或當所有對象已經(jīng)枚舉完成時:為nil。
3、@property(readonly, copy) NSArray<ObjectType> *allObjects;
返回:未枚舉對象的數(shù)組
該數(shù)組按枚舉順序包含枚舉器中所有剩余對象。
它不包含之前已經(jīng)調(diào)用nextObject消息的枚舉對象。
訪問該屬性會耗盡枚舉器集合,這會導致隨后調(diào)用nextObject會返回nil。
.
.
.
以下內(nèi)容未驗證
基于塊的枚舉
在iOS 4中為Cocoa Touch框架中的集合對象引入了基于塊的枚舉(Block-Based Enumeration)。塊是Objective-C的一項語言功能(本書寫作時,蘋果公司還在爭取把塊作為對C語言的擴展而標準化)。塊是一種類型化的函數(shù),就是說塊是函數(shù)也是類型。定義好的塊是一個可在方法調(diào)用之間傳遞的變量,就跟對象中的其他變量一樣。同時,塊變量在方法中可作為函數(shù)使用。當把塊作為參數(shù)傳遞給方法時,塊可以像C程序中的函數(shù)指針那樣被用作回調(diào)函數(shù)。因此塊正適合于實現(xiàn)內(nèi)部迭代器(枚舉器)。客戶端不再需要手動生成迭代器,只需要提供一個符合目標集合對象所要求的簽名的塊。然后塊將在每個遍歷步驟中被調(diào)用。在每次塊被目標集合對象調(diào)用時,定義塊的算法可以對返回的元素進行處理。
塊是Objective-C語言中很酷的一項功能。它讓我們可以把回調(diào)算法的定義內(nèi)嵌在消息調(diào)用之中。如果不使用塊,在Cocoa Touch框架中實現(xiàn)“回調(diào)”的傳統(tǒng)方式是使用委托(見適配器模式,第8章)。需要為要響應(yīng)客戶端回調(diào)的所有對象(適配器)單獨定義一個協(xié)議(目標)。要是應(yīng)用程序的這個部分復(fù)雜到需要另外的適配器機制的程度,那也未嘗不可。有時塊可以提供一種比枚舉器更漂亮的解決方案。
在iOS 4中,蘋果公司在NSArray、NSDictionary和NSSet對象中引入了新方法,用于基于塊的枚舉。其中一個方法叫enumerateObjectsUsingBlo<wbr style="box-sizing: border-box;">ck:(void (^)(id obj, NSUInteger idx, BOOL *stop))block。我們可以把自己的算法定義在內(nèi)嵌到消息調(diào)用之中的塊里,或者在別的什么地方預(yù)先定義一個塊,然后作為參數(shù)傳給消息調(diào)用。下面的代碼段通過一個NSArray對象演示了它是如何在代碼中實現(xiàn)的。
NSArray *anArray=[NSArray arrayWithObjects:@"This", @"is", @"a", @"test", nil];
NSString *string=@"test";
[anArray enumerateObjectsUsingBlock:^(id obj, NSUInteger index, BOOL *stop)
{
if([obj localizedCaseInsensitiveCompare:string] == NSOrderedSame)
{
// 對返回的obj做點別的事情
*stop=YES;
}
要是anArray對象中有個單詞是@"test",那么就把指針*stop設(shè)置為YES,以通知anArray對象提前停止枚舉。塊除了id obj和BOOL *stop參數(shù),還有一個NSUInteger index參數(shù)。index參數(shù)讓塊中的算法知道當前元素的位置,這對這樣的并發(fā)枚舉非常有用。要是沒有這個參數(shù),訪問索引的唯一方式就是使用indexOfObject:方法,這樣影響效率。
NSSet對象中基于塊的枚舉與NSArray對象中的非常類似,只是在塊簽名中沒有index參數(shù)。NSSet對象是一種模擬“集合”(set)的數(shù)據(jù)結(jié)構(gòu),集合中的元素沒有表示元素在結(jié)構(gòu)中位置的索引。
使用NSArray、NSDictionary和NSSet的內(nèi)部迭代器的一個重要好處是,處理其內(nèi)容的算法可在其他地方由其他開發(fā)人員來定義。與傳統(tǒng)的for循環(huán)中定義的算法不同,定義清晰的塊可被復(fù)用。當塊逐漸變大時,可把它們放到單獨的實現(xiàn)文件中,不跟其他代碼擠在一起。雖然塊是一種為復(fù)雜的事物添加內(nèi)聯(lián)算法的方便途徑,無需定義單獨的委托協(xié)議,但是當塊過大而難以維護時,應(yīng)該考慮使用策略模式(第19章)。
<a name="t1" style="box-sizing: border-box; background: transparent; color: rgb(79, 161, 219); text-decoration: none; margin: 0px; padding: 0px; font-weight: normal; outline: none;"></a>快速枚舉
Objective-C 2.0提供了一種枚舉,稱為快速枚舉。它是蘋果公司推薦的枚舉方法。它允許把對集合對象的枚舉直接用作for循環(huán)的一部分,無需使用其他枚舉器對象,而且比傳統(tǒng)的基于索引的for循環(huán)效率更高??焖倜杜e的語法如下。
NSArray * anArray = ... ;
for (NSString * item in anArray)
{
// 對item作些處理
}
現(xiàn)在枚舉循環(huán)使用指針運算(pointer arithmetic),讓它比使用NSEnumerator的標準方法效率更高。
要利用快速枚舉,集合類需要實現(xiàn)NSFastEnumeration協(xié)議,以向運行庫提供關(guān)于集合的必要信息。基礎(chǔ)框架中的所有集合類與NSEnumerator類都支持快速枚舉。因此不必使用while循環(huán)從NSEnumerator枚舉每個元素,直到nextObject返回nil,我們可以使用其快速枚舉的版本,如下面的代碼段所示。
NSArray * anArray = ... ;
NSEnumerator * itemEnumerator = [anArray objectEnumerator];
for (NSString * item in itemEnumerator)
{
// 對item作些處理
}
雖然既可以使用集合對象的快速枚舉,也可以使用枚舉器的快速枚舉,但如果只需要默認遍歷(通常只按升序),直接對集合對象進行快速枚舉更為合理。NSEnumerator使用其nextObject方法實現(xiàn)NSFastEnumeration協(xié)議。從性能上說,它比直接在while循環(huán)中手動調(diào)用這個方法好不了多少。盡管跟傳統(tǒng)的使用nextObject的while循環(huán)相比,快速枚舉中的for循環(huán)顯得更為整潔。
實現(xiàn)NSFastEnumeration不在本書的范圍,所以不在此討論它。
<a name="t2" style="box-sizing: border-box; background: transparent; color: rgb(79, 161, 219); text-decoration: none; margin: 0px; padding: 0px; font-weight: normal; outline: none;"></a>內(nèi)部枚舉
NSArray有個實例方法叫(void)makeObjectsPerformSelect<wbr style="box-sizing: border-box;">or:(SEL)aSelector,它允許客戶端向數(shù)組中每個元素發(fā)送一個消息,讓每個元素執(zhí)行指定的aSelector(假定元素支持它)??梢杂们懊嫣岬降娜魏我环N枚舉方法讓每個元素執(zhí)行相同的選擇器,達到相同的目的。這個方法在內(nèi)部枚舉集合并向每個元素發(fā)送performSelector:消息。這種方式的缺點是如果集合中任何元素不響應(yīng)選擇器,就會拋出異常。因此它主要適用于不需太多運行時檢查的簡單操作。
原文鏈接1: http://blog.sina.com.cn/s/blog_7cdd1b3501010076.html
原文鏈接2:http://blog.csdn.net/hdfqq188816190/article/details/52754406