2011-07-26 78 views
4

考慮下面的代碼。本質上,我們得到2個字符串,然後我們將這些值添加到NSDictionary。NSDictionary如何處理NIL對象?

但是,我遇到了一個奇怪的錯誤。當fbAccessTokenKey是0x0(或零),那麼twitterToken也不會被添加。

NSString *fbAccessTokenKey=[[UserStockInfo sharedUserStockInfo] getFBAccessTokenKey]; 
NSString *twitterToken=[[UserStockInfo sharedUserStockInfo] getTwitterAccessTokenKey]; 

NSDictionary *params= [[NSDictionary alloc] initWithObjectsAndKeys: 
         fbAccessTokenKey, @"fb_access_token", 
         twitterToken, @"twitter_access_token", 
         nil 
         ]; 

爲什麼會發生這種情況,解決這個問題的好方法是什麼?

回答

13

nil作爲標記「參數結束」列表的「標記」。如果twitterToken爲零,則運行時會經過您的參數,一旦達到twitterToken,它會認爲它已經到達對象和密鑰列表的末尾。這是由於C/Obj-C在列表參數中實現的方式。

替代安全的方式做到這一點是使用NSMutableDictionary,並請檢查您的值不爲零,然後將它們添加到可變的字典是這樣的:

NSString *fbAccessTokenKey = [[UserStockInfo sharedUserStockInfo] getFBAccessTokenKey]; 
NSString *twitterToken = [[UserStockInfo sharedUserStockInfo] getTwitterAccessTokenKey]; 

NSMutableDictionary *params = [NSMutableDictionary dictionary]; 
if (fbAccessTokenKey) [params setObject:fbAccessTokenKey forKey:@"fb_access_token"]; 
if (twitterToken) [params setObject:twitterToken forKey:@"twitter_access_token"]; 

對於更多技術信息,還有一篇關於Cocoa with Love的好文章:http://cocoawithlove.com/2009/05/variable-argument-lists-in-cocoa.html

+0

感謝您的好解釋!我知道了。 –

+0

即使我每天都使用它,我甚至沒有想過這個。謝謝! – Sirens

2

而不是使用initWithObjectAndKeys進行初始化。爲什麼不實例化一個NSMutableDictionary,然後添加鍵值對(或者如果鍵爲空,則不需要)?

NSMutableDictionary * params = [[NSMutableDictionary alloc] init]; 

if (fbAccessTokenKey) 
    [params setObject:fbAccessTokenKey forKey:@"fb_access_token]; 

// ... etc 

如果你想從這一點上保持它不可變,你可以稍後將它轉換回NSDictionary。

更新

響應Josh's評論剛一說明,我要澄清,當然劇組也不會神奇地轉換PARAMS的NSMutableDictionary到一個NSDictionary。但是,如果您將它傳遞給需要NSDictionary的代碼,那麼演員陣容可以讓您對待它。

Josh的評論包括這樣的代碼:

NSMutableDictionary * md = [[NSMutableDictionary alloc] init]; 
NSDictionary * d = (NSDictionary *)md; 
[d setObject:@"Yes I am" forKey:@"Still mutable?"]; 
NSLog(@"%@", d); // Prints { "Still mutable?" = Yes I am; } 

這將生成以下編譯器警告(對我來說,有警告產生的錯誤,編譯錯誤):

file:blah.m: error: Semantic Issue: 'NSDictionary' may not respond to 'setObject:forKey:'

+0

感謝您的建議投它nsdict - 工作就像一個魅力;) –

+0

@銘耀高興的是,幫助:) – RedBlueThing

+0

鑄造在編譯時有發生,並且不能影響的可變性object:'NSMutableDictionary * md = [[NSMutableDictionary alloc] init]; NSDictionary * d =(NSDictionary *)md; [d setObject:@「Yes I am」forKey:@「Still mutable?」]; NSLog(@「%@」,d); //打印{「仍然可變嗎?」 =是的,我是; }' –