爲什麼有valueForKey:和intForKey:,stringForKey :,等爲什麼在objC中沒有* ForKeyPath?
但有valueForKeyPath:和沒有intForKeyPath:,stringForKeyPath :,等等?
爲什麼有valueForKey:和intForKey:,stringForKey :,等爲什麼在objC中沒有* ForKeyPath?
但有valueForKeyPath:和沒有intForKeyPath:,stringForKeyPath :,等等?
Apple的NSDictionary
不支持名爲intForKey:
或stringForKey:
的消息。
也許你正在使用一些第三方庫,將這些消息添加到一個類別中。您可以詢問該庫的作者爲什麼不包含這些消息的keypath版本。
也許您正在考慮NSUserDefaults
,而不是NSDictionary
。 NSUserDefaults
瞭解integerForKey:
和stringForKey:
。 NSUserDefaults
不適用於存儲大型複雜結構。它旨在用於存儲小而簡單的數據。
您正在混合來自2個不同對象(實際上是1個對象和一個非正式協議)的方法名稱:NSUserDefaults
和NSKeyValueCoding
非正式協議。
NSUserDefaults
已經存在了很長時間,而鍵值編碼和鍵值觀察只是在OS X 10.3以後纔有。
NSUserDefaults
涉及存儲與屬性列表兼容的對象(NSData,NSDate,NSString,NSArray和NSDictionary),以實現應用程序啓動之間的持久性。應用程序通常需要存儲非對象類型值,如BOOL或整數,但僅支持對象,因此這些便捷方法(intForKey:
,boolForKey:
等)允許以更簡潔的方式保存它們。例如,代碼
[[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithBool:NO] forKey:MDFirstLaunchKey];
以下行變成:
[[NSUserDefaults standardUserDefaults] setBool:NO forKey:MDFirstLaunchKey];
相應的「獲取」方法允許更簡潔的代碼以獲得非對象類型值。
NSUserDefaults
這些方法的另一個目的是驗證對象類型。比方說,你已經下了關鍵MDClientsKey
保存的NSDictionary
秒的NSArray
,你誤寫下面的代碼:
NSDictionary *client = [userDefaults objectForKey:MDClientsKey];
NSString *name = [client objectForKey:@"name"];
的Objective-C的動態特性意味着對象用戶默認值將返回爲objectForKey:
調用將不是代碼假設的NSDictionary
,而是NSArray
。後續行會嘗試在NSArray上調用objectForKey:
,這可能會引發NSInvalidArgumentException並導致應用程序崩潰。
如果您已經改用dictionaryForKey:
,NSUserDefaults
將返回nil
:
NSDictionary *client = [userDefaults dictionaryForKey:MDClientsKey];
NSString *name = [client objectForKey:@"name"];
下一行會那麼意味着你將消息發送到nil
,它會被忽略(換句話說,沒有崩潰) 。
另一方面,valueForKey:
和valueForKeyPath:
方法是NSKeyValueCoding
非正式協議的一部分。他們基本上允許一個對象通過名稱使用NSString
來訪問另一個對象的實例變量,而不必調用一個方法。這方面的一個關鍵部分是,valueForKey:
和valueForKeyPath:
需要返回對象,而不是原始的類型,如int
或float
,等等。事實上,如果一個對象有一個height
屬性,是一種原始類型像NSInteger
,呼籲[object valueForKeyPath:@"height"]
將automatically wrap它返回一個NSNumber
。正因爲如此,擴展*ForKeyPath:
訪問器並沒有多大意義。
這是因爲蘋果希望程序員使用他們的技能 –
如果你想要,你可以添加一個類別 – nielsbot