快還要更快!使用 NSDictionary 迭代取值法來印出 NSDictionary 全部的資料

NSDictionary 是 Objective-C 中一個相當好用的東西,很類似 Java 中的 Map 物件,都是以 key-Value 的方式儲存資料。Objective-c 在處理 JSON 資料時,也會將資料轉成 NSDictionary 的方式儲存。而在海芋最近使用 NSDictionary 的物件,必須將 NSDictionary 中的資料全部印出來,這時怎麼辦呢?

其實,在 Objective-C 中,就有一個函式 enumerateKeysAndObjectsUsingBlock,就可以一次繞完整個 NSDictionary 了,而這個函式在官方的定義如下:

- (void)enumerateKeysAndObjectsUsingBlock:(void (^)(KeyType key, ObjectType obj, BOOL *stop))block;
 

看到這,或許你就會知道了,他是使用 Block 的方式做處理,而有三個參數,第一個參數 key 就是 NSDictionary 的 key,obj 就是 NSDictionary 的 Value,*stop 就是要不要停止的意思。

舉例來說,如果你一開始建了一個 NSMutableDictionary,如下:

NSMutableDictionary* m_mapRequestCache;
m_mapRequestCache = [[[NSMutableDictionary alloc] init] autorelease];
m_mapRequestCache["0"] = @(0);
m_mapRequestCache["1"] = @(1);
m_mapRequestCache["2"] = @(2);

如果你想依序印出全部的 key 和 Value,有些人會教你用「allKeys」先去取出全部的 key 值,再從 key 值用「objectForKey」去得到 Value 這樣的寫法。

   for (NSString* key in m_mapRequestCache.allKeys){
    NSLog("key=%@, Value=%d", key, 
                 [[m_mapRequestCache objectForKey: key] intValue]);
}

這樣寫並沒有不對,但因為 NSDictionary 是循序的,但我們取出全部 key 值後,要印出全部的資料就已經要跑一次迴圈了,如果再用 key 值再去取 Value 的話,等於系統會再去繞一次 NSDictionary 去取出 key 值對應的 Value,就顯得很秏時間,這時用 enumerateKeysAndObjectsUsingBlock 的好處就顯現了,他只要繞一次 NSDictionary,就可以將全部的 key 值和 Value 值印出來。寫法如下:

[m_mapRequestCache enumerateKeysAndObjectsUsingBlock:^(NSString* key, NSNumber* value, BOOL* stop) {
     NSLog("key=%@, Value=%d", key, [value intValue]);
}

但是如果你想在印出 key 值字串為 0 後的數字後,就停止接下來的動作,也就是不要繼續在 NSMutableDictionary 繞,那麼你必須寫成這樣。

[m_mapRequestCache enumerateKeysAndObjectsUsingBlock:^(NSString* key, NSNumber* value, BOOL* stop) {
     if ([key isEqualToString:@"0"]){
         *stop = YES;
     }
     NSLog("key=%@, Value=%d", key, [value intValue]);
}
 

但如果你想在印出 key 值字串為 0、2 的數字,而不想印出 key 值字串為 1 的數字,那麼你必須使用 return 來結束 Block,在這裡, return 有點像是迴圈中的 continue,而不是將*stop 設為 yes,若將 *stop 設為 yes 的話, key 值字串為 2 就不會執行了。所以必須寫成這樣。

[m_mapRequestCache enumerateKeysAndObjectsUsingBlock:^(NSString* key, NSNumber* value, BOOL* stop) {
     if ([key isEqualToString:@"1"]){
         return;
     }
     NSLog("key=%@, Value=%d", key, [value intValue]);
}

最後,再次說明, enumerateKeysAndObjectsUsingBlock 會是一個去繞 NSDictionary,然後循序取出 NSDictionary 中的 key 值和 Value 值的方法,如果只是要取特定的 key 值對應的 Value,那麼直接用「objectForKey」這個函式就好了。

Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments