1. 程式人生 > >kvc和kvo的使用情況的了解

kvc和kvo的使用情況的了解

sele enter acc 組合 ets 字符串 exp ace map

了解cocoa:Cocoa是蘋果公司為Mac OS X所創建的原生面向對象的API,是Mac OS X上五大API之中的一個(其他四個是Carbon、POSIX、X11和Java)。

蘋果的面向對象開發框架,用來生成 Mac OS X 的應用程序。基本的開發語言為 Objective-c, 一個c 的超集。

即為:Coroa 基本面向原生的API抽象。是C的一個超級。


在Cocoa中是以被萬物之源NSObject類實現的NSKeyValueCoding(鍵值編碼)/(鍵值觀察)NSKeyValueObserving 非正式協議 的形式被定義為基礎框架的一部分。

=
NSKeyValueCoding 是一個非正式的協議。(線管的內容能夠看西面羅列的方法)

KVC/KVO實現的根本是Objective-C的 動態性和runtime
KVC/KVO機制離不開訪問器方法的實現。



kvc
相似c++中的map類的使用。
它提供了一種使用“字符串”而不是“訪問器(方法)”方法去訪問一個對象實例變量的機制。
kvo ?
提供了一種當其他對象屬性被改動的時候能通知當前對象的機制.
KVO機制非常適合實現model和controller類之間的通訊。

總結全部的方法差點兒能夠使用以下的四個方法為代表。


//一般的都是這幾個方法
<span style="color:#990000;">- (id)valueForKey:(NSString *)key;
- (void)setValue:(id)value forKey:(NSString *)key;</span>
Key——>鍵值 , 就是要訪問的屬性名稱(key)相應的字符串。

(用數組(索引)的方式似乎沒有什麽區別) <span style="color:#CC0000;">- (id)valueForKeyPath:(NSString *)keyPath; - (void)setValue:(id)value forKeyPath:(NSString *)keyPath;</span> 後面的KeyPath是一個被點操作符隔開的用於訪問對象的指定屬性的字符串序列。(keypath 就是大範圍到小範圍逐漸到詳細的地方) eg:eyPath address.street將會訪問消息接收對象所包括的address屬性中包括的一個street屬性。 事實上KeyPath說白了就是我們平時使用點操作訪問某個對象的屬性時所寫的那個字符串。




點語法和kvc之間的區別:
在實現了訪問器方法的類中,使用點語法和KVC訪問對象事實上區別不大,二者能夠隨意混用。可是沒有訪問起方法的類中,點語法無法使用,這時KVC就有優勢了。( 原因見第三部分的第一節:KVC怎樣訪問屬性值。

) ??

一對多的關系:(數據中常常會存在)
?①間接操作
先通過KVC方法取到集合屬性,然後通過集合屬性操作集合中的元素。


?②直接操作 (基本上是不適用)
?
?4、鍵值驗證(Key-Value Validation)
KVC提供了驗證Key相應的Value是否可用的方法:
- (BOOL)validateValue:(inout id *)ioValue forKey:(NSString *)inKey error:(out NSError **)outError;

該方法默認的實現是調用一個例如以下格式的方法:
- (BOOL)validate<Key>:error:

比方屬性name相應的方法為:
-(BOOL)validateName:(id *)ioValue error:(NSError * __autoreleasing *)outError {
??? return ;
}

KVC是不會自己主動調用鍵值驗證方法的 。就是說我們須要手動驗證。可是有些技術,比方CoreData會自己主動調用。

?5、KVC對數值和結構體型屬性的支持

?總結一下,想使用KVO有三種方法:
1)使用了KVC
使用了KVC,假設有訪問器方法,則執行時會在訪問器方法中調用 will/didChangeValueForKey:方法;
沒用訪問器方法,執行時會在setValue:forKey方法中調用 will/didChangeValueForKey:方法。


2)有訪問器方法
執行時會重寫訪問器方法調用 will/didChangeValueForKey:方法。
因此,直接調用訪問器方法改變屬性值時,KVO也能監聽到。
3)顯示調用will/didChangeValueForKey:方法。
總之。想使用KVO,僅僅要有 will/didChangeValueForKey:方法就能夠了。


③ _isKVOA
這個私有方法預計是用來標示該類是一個 KVO 機制聲稱的類。


長處和缺點

1、長處
①能夠再非常大程度上簡化代碼
樣例網上非常多。這就不舉了
②能跟腳本語言非常好的配合
才疏學淺,沒學過AppleScript等腳本語言,所以沒能深刻體會到該長處。
2、缺點
KVC的缺點不明顯,基本的kvo的缺點如連接:http://www.mikeash.com/pyblog/key-value-observing-done-right.html
核心思想是說KVO的回調機制,不能傳一個selector或者block作為回調。而必須重寫-addObserver:forKeyPath:options:context:方法所引發的一系列問題。問了解決問題。作者還親自實現了一個MAKVONotificationCenter類。代碼見github:
https://github.com/mikeash/MAKVONotificationCenter
只是個人覺得這僅僅是蘋果做的KVO不夠完美,不能算是缺陷。


關於NSKeyValueCoding.h這個文件愛你的屬性的了解。

#import <Foundation/NSArray.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSOrderedSet.h>
#import <Foundation/NSSet.h>

@class NSError, NSString;

FOUNDATION_EXPORT NSString *const NSUndefinedKeyException;
FOUNDATION_EXPORT NSString *const NSAverageKeyValueOperator;
FOUNDATION_EXPORT NSString *const NSCountKeyValueOperator;
FOUNDATION_EXPORT NSString *const NSDistinctUnionOfArraysKeyValueOperator;
FOUNDATION_EXPORT NSString *const NSDistinctUnionOfObjectsKeyValueOperator;
FOUNDATION_EXPORT NSString *const NSDistinctUnionOfSetsKeyValueOperator;
FOUNDATION_EXPORT NSString *const NSMaximumKeyValueOperator;
FOUNDATION_EXPORT NSString *const NSMinimumKeyValueOperator;
FOUNDATION_EXPORT NSString *const NSSumKeyValueOperator;
FOUNDATION_EXPORT NSString *const NSUnionOfArraysKeyValueOperator;
FOUNDATION_EXPORT NSString *const NSUnionOfObjectsKeyValueOperator;
FOUNDATION_EXPORT NSString *const NSUnionOfSetsKeyValueOperator;

@interface NSObject(NSKeyValueCoding)

+ (BOOL)accessInstanceVariablesDirectly;
- (id)valueForKey:(NSString *)key;
- (void)setValue:(id)value forKey:(NSString *)key;
- (BOOL)validateValue:(inout id *)ioValue forKey:(NSString *)inKey error:(out NSError **)outError;
- (NSMutableArray *)mutableArrayValueForKey:(NSString *)key;
- (NSMutableOrderedSet *)mutableOrderedSetValueForKey:(NSString *)key NS_AVAILABLE(10_7, 5_0);
- (NSMutableSet *)mutableSetValueForKey:(NSString *)key;

- (id)valueForKeyPath:(NSString *)keyPath; //這個是有關路徑的字符串。這個是怎麽用的?

- (void)setValue:(id)value forKeyPath:(NSString *)keyPath;
- (BOOL)validateValue:(inout id *)ioValue forKeyPath:(NSString *)inKeyPath error:(out NSError **)outError;

- (NSMutableArray *)mutableArrayValueForKeyPath:(NSString *)keyPath;
- (NSMutableOrderedSet *)mutableOrderedSetValueForKeyPath:(NSString *)keyPath NS_AVAILABLE(10_7, 5_0);
- (NSMutableSet *)mutableSetValueForKeyPath:(NSString *)keyPath;
- (id)valueForUndefinedKey:(NSString *)key;
- (void)setValue:(id)value forUndefinedKey:(NSString *)key;
- (void)setNilValueForKey:(NSString *)key;
- (NSDictionary *)dictionaryWithValuesForKeys:(NSArray *)keys;
- (void)setValuesForKeysWithDictionary:(NSDictionary *)keyedValues;
@end

//定的數組
@interface NSArray(NSKeyValueCoding)
- (id)valueForKey:(NSString *)key;
- (void)setValue:(id)value forKey:(NSString *)key;
@end

//字典的兩種方式進行組合
@interface NSDictionary(NSKeyValueCoding)
- (id)valueForKey:(NSString *)key;
@end
@interface NSMutableDictionary(NSKeyValueCoding)
- (void)setValue:(id)value forKey:(NSString *)key;
@end

@interface NSOrderedSet(NSKeyValueCoding)
- (id)valueForKey:(NSString *)key;
- (void)setValue:(id)value forKey:(NSString *)key;
@end

@interface NSSet(NSKeyValueCoding)
- (id)valueForKey:(NSString *)key;
- (void)setValue:(id)value forKey:(NSString *)key;
@end

#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
//TARGET_OS_EMBEDDED這個表示是嵌入式的方式
//TARGET_OS_IPHONE iphone 開發
//TARGET_OS_MAC os系統開發

@interface NSObject(NSDeprecatedKeyValueCoding)
+ (BOOL)useStoredAccessor ;
- (id)storedValueForKey:(NSString *)key ;
- (void)takeStoredValue:(id)value forKey:(NSString *)key;
- (void)takeValue:(id)value forKey:(NSString *)key ;
- (void)takeValue:(id)value forKeyPath:(NSString *)keyPath ;
- (id)handleQueryWithUnboundKey:(NSString *)key;
- (void)handleTakeValue:(id)value forUnboundKey:(NSString *)key;
- (void)unableToSetNilForKey:(NSString *)key;
- (NSDictionary *)valuesForKeys:(NSArray *)keys ;
- (void)takeValuesFromDictionary:(NSDictionary *)properties;

@end
#endif




kvc和kvo的使用情況的了解