KVC是如何通過key來存取屬性的?這里是有一套規(guī)則的:
valueForKey:的查找規(guī)則
- 查找是否存在比較直接的訪問方法。按照get<Key>, <key>, is<Key>, _<key>的順序,如果找到就調(diào)用該方法并帶著結(jié)果到步驟5,否則到第2步繼續(xù)查找。
- 查找是否存在類似數(shù)組的方法。首先查找是否存在countOf<Key>方法,再查找是否有objectIn<Key>AtIndex:或<key>AtIndexes: 其中一個(gè)方法,如果找到,則會(huì)返回一個(gè)代理對象,該對象類似一個(gè)數(shù)組,數(shù)組含有的元素個(gè)數(shù)為第一個(gè)方法返回值,數(shù)組內(nèi)的元素就是第二個(gè)方法返回值。在這種情況下不管屬性是否是數(shù)組,kvc的返回值都是數(shù)組,實(shí)際類為NSKeyValueArray。
如果未找到上述方法,到第3步繼續(xù)查找。 - 查找是否存在類似NSSet的方法。查找是否有countOf<Key>, enumeratorOf<Key>, 和 memberOf<Key>:三個(gè)方法,如果有則返回一個(gè)代理對象 ,該對象類似一個(gè)NSSet,和第2步類似。
如果未找到上述3個(gè)方法,到第4步繼續(xù)查找。 - 直接查找實(shí)例變量。按照_<key>, _is<Key>, <key>, is<Key>的順序,如果找到則直接獲取變量并到步驟5,否則到步驟6。
- 如果得到的值是一個(gè)對象,直接返回結(jié)果。
如果得到一個(gè)可轉(zhuǎn)為NSNumber非對象值,轉(zhuǎn)為NSNumber并返回。
如果得到一個(gè)不可轉(zhuǎn)為NSNumber的非對象值,如結(jié)構(gòu)體,轉(zhuǎn)為NSValue并返回。 - 未找到,調(diào)用valueForUndefinedKey:方法。
setValue:forKey:的查找規(guī)則
- 查找是否存在比較直接的訪問方法。按照set<Key>:,_set<Key>的順序,如果找到則調(diào)用該方法。否則到步驟2繼續(xù)查找。
- 直接查找實(shí)例變量。按照_<key>, _is<Key>, <key>, is<Key>的順序,如果找到直接設(shè)置變量。否則到步驟3。
- 未找到,調(diào)用setValue:forUndefinedKey:方法。
mutableArrayValueForKey:的查找規(guī)則
總是返回一個(gè)可變代理數(shù)組,遵循如下規(guī)則
- 查找insertObject:in<Key>AtIndex: removeObjectFrom<Key>AtIndex:,insert<Key>:atIndexes: 和 remove<Key>AtIndexes:這些方法。如果找到至少一個(gè)插入方法和至少一個(gè)刪除方法,則返回一個(gè)代理對象,該對象對于可變數(shù)組的插入和刪除的響應(yīng)會(huì)轉(zhuǎn)至上述方法。
- 沒有找到上述可變數(shù)組的類似方法,則查找set<Key>:方法,返回一個(gè)代理對象,該對象對可變數(shù)組的插入和刪除操作都會(huì)調(diào)用該方法。
- 前2步都未找到,直接查找實(shí)例變量,按照_<key> ,<key>的順序,返回一個(gè)代理對象,該對象對可變數(shù)組的方法都會(huì)直接轉(zhuǎn)發(fā)至實(shí)例變量,該變量最好是一個(gè)可變數(shù)組類,否則可能出現(xiàn)異常。
- 上述都未找到,依然返回一個(gè)可變代理數(shù)組,其接收到的可變數(shù)組的操作都會(huì)調(diào)用setValue:forUndefinedKey:方法。
值得注意的是,在滿足上述步驟1或步驟2后,返回值會(huì)遵循valueForKey:的查找規(guī)則。
mutableOrderedSetValueForKey:和mutableSetValueForKey:查找規(guī)則
與mutableArrayValueForKey:類似,有興趣的可查看官方文檔或API說明