基礎(chǔ)知識之KVC原理

在開發(fā)中,我們可以通過使用 KVC 的方式來對某個對象的屬性進(jìn)行賦值/取值操作。

經(jīng)常會用到以下 API:

// 設(shè)置值
- (void)setValue:(nullable id)value forKey:(NSString *)key;

- (void)setValue:(nullable id)value forKeyPath:(NSString *)keyPath;

// 獲取值
- (nullable id)valueForKeyPath:(NSString *)keyPath;

- (nullable id)valueForKey:(NSString *)key;
1、賦值操作

KVC的調(diào)用原理:
如果我們給某個類定義一個屬性,那么編譯器會自動生成getter和setter方法,如果通過KVC給該屬性進(jìn)行賦值操作,默認(rèn)會調(diào)用setter方法進(jìn)行賦值,但是這不能完全搞清楚KVC是如何工作的。
現(xiàn)在我們定義一個Person類,但是我們并不給Person定義任何的屬性,接下來創(chuàng)建person對象,通過KVC的方式給person的age屬性進(jìn)行賦值操作。

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        
        Person *person = [[Person alloc] init];
        
        [person setValue:@(40) forKey:@"age"];
    }
    return 0;
}

接下來是執(zhí)行順序,去Person類中查找有沒有- (void)setAge:方法,如果有那么就進(jìn)行賦值操作;如果沒有再去查找有沒有- (void)_setAge: 方法,如果有就進(jìn)行賦值的操作,如果以上2個方法都沒找到,那么就會調(diào)用- (Bool)accessInstanceVariablesDirectly 方法,該方法是詢問是否可以直接訪問成員變量,返回NO就直接拋出異常未定的key,返回YES(如果不實(shí)現(xiàn)該方法默認(rèn)返回就是YES),那么就直接去成員變量中按順序查找以下成員變量:_age、_isAge、age、isAge。如果找到4個成員變量中的1位,那么就進(jìn)行賦值,否則拋出異常未定義的key。

2、取值操作

KVC 的取值操作也會按照一定的順序進(jìn)行操作的。
在取值的過程中,按照-(int)getAge、-(int)age、-(int)isAge-(int)_age順序進(jìn)行,看有沒有實(shí)現(xiàn)這4個方法中的其中1個,如果有那么調(diào)用,如果沒有實(shí)現(xiàn)上面的4個方法,繼續(xù)查看 + (BOOL)accessInstanceVariablesDirectly 方法的返回值是否為 YES,如果為NO,直接拋出異常,如果為YES,那么就去按順序查找Person的成員變量是不是_age,_isAge、age、isAge中的一個,如果有4個成員變量中的1個,那么就取他們的值。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容