KVC設(shè)值過程

在KVC的實(shí)現(xiàn)中,依賴setter和getter的方法實(shí)現(xiàn),所以方法命名應(yīng)該符合蘋果要求的規(guī)范,否則會(huì)導(dǎo)致KVC失敗。

setValue的過程

先看一個(gè)很有趣的問題


@interface ViewController ()

@property (nonatomic, strong) NSString *Str;
@property (nonatomic, strong) NSString *str;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    
    // 情況1
    self.Str = @"大寫";
    self.str = @"小寫";
    
    NSLog(@"str:%@----Str:%@",_str,_Str);
    
    // 輸出  str:(null)----Str:小寫
    
    // 情況2
//    self.Str = @"大寫";
    self.str = @"小寫";

    NSLog(@"str:%@----Str:%@",_str,_Str);
    
    // 輸出  str:(null)----Str:小寫
    
    
    // 情況3
    self.Str = @"大寫";
//    self.str = @"小寫";
    
    NSLog(@"str:%@----Str:%@",_str,_Str);
    
    // 輸出   str:(null)----Str:大寫
}

輸出:(null)----123

也就是說,當(dāng)有同名大小寫屬性時(shí),遵守駝峰標(biāo)識(shí)的屬性會(huì)失效,也就是小寫開頭的屬性

為什么小寫開頭的屬性會(huì)失效呢???

我們從setter方法找起

我們會(huì)發(fā)現(xiàn)ocsetter方法是遵守駝峰標(biāo)識(shí)的,比如setStr:(NSString *)Str

所以我的猜想:既然是setStr。。。。。那么有_Str的實(shí)例變量就優(yōu)先給他賦值,沒有就給_str賦值

我們嘗試下

[self setValue:@"大寫" forKey:@"Str"];
[self setValue:@"小寫" forKey:@"str"];

結(jié)果還是一樣

回歸主題,我們調(diào)用[self setValue:@"大寫" forKey:@"Str"];這個(gè)的時(shí)候,會(huì)先調(diào)用這個(gè)屬性的set方法.

那么問題也來了,如果這時(shí)候的key是沒有的屬性或者nil,那么就會(huì)導(dǎo)致調(diào)用setKey的時(shí)候,找不到方法導(dǎo)致崩潰

所以,我們可以封裝類似醬紫的安全方法

- (void)safeSetValue:(NSString *)value forKey:(NSString *)key
{
    if (![key isKindOfClass:[NSString class]])
    {
        return;
    }
    
    @try {
        [self setValue:value forKey:key];
    }@catch(NSException *exception){}@finally {}
}

沒有找到setKey:方法的時(shí)候

KVC機(jī)制會(huì)檢查
+ (BOOL)accessInstanceVariablesDirectly方法有沒有返回YES,默認(rèn)該方法會(huì)返回YES,如果你重寫了該方法讓其返回NO的話,那么在這一步KVC會(huì)執(zhí)行setValue:forUNdefinedKey:方法

一般我們不會(huì)閑得蛋疼去重寫+ (BOOL)accessInstanceVariablesDirectly方法,

所以這時(shí)候既然setKey:方法找不到了,就只能硬干了,直接去找對(duì)應(yīng)的成員變量賦值,

所以說,就算是只讀屬性(只讀屬性沒有set方法),這時(shí)候用kvc也可以賦值,因?yàn)檎也坏?code>set方法,直接對(duì)成員變量賦值

那如果找不到成員變量呢???

如果都沒有找到,那么就只能調(diào)用valueforUndefinedKeysetValue:forUNdefinedKey:(沒有定義這個(gè)key)拋異常

應(yīng)用

提一個(gè)問題:+ (BOOL)accessInstanceVariablesDirectly

什么時(shí)候重寫這個(gè)方法,返回NO

但我們重寫這個(gè)方法,返回NO的時(shí)候,外部對(duì)這個(gè)類進(jìn)行kvc的時(shí)候,就沒那么容易了,因?yàn)楫?dāng)找不到set方法,就直接失敗了嘛

所以你想要這個(gè)類,足夠封閉,安全的時(shí)候,可以重寫這個(gè)方法,尤其是設(shè)置SDK的時(shí)候使用

字典轉(zhuǎn)模型

服務(wù)端返回字段,有可能是id,或者其他oc的系統(tǒng)保留字段

那么就可以重寫這方法,在這塊地方去統(tǒng)一處理


- (void)setValue:(id)value forUndefinedKey:(NSString *)key
{
    
}

valueForKey:搜索過程

有點(diǎn)多,復(fù)雜

這個(gè)文章講得不錯(cuò)

Tips

如果valueForKeyPath:方法的調(diào)用者是數(shù)組,那么就是去訪問數(shù)組元素的屬性值

應(yīng)用:模型轉(zhuǎn)字典

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • KVC(Key-valuecoding)鍵值編碼,單看這個(gè)名字可能不太好理解。其實(shí)翻譯一下就很簡單了,就是指iOS...
    榕樹頭閱讀 723評(píng)論 0 2
  • KVC是Key Value Coding的簡稱。它是一種可以通過字符串的名字(key)來訪問類屬性的機(jī)制。而不是通...
    _李恒閱讀 754評(píng)論 0 0
  • KVC是Key Value Coding的簡稱。它是一種可以通過字符串的名字(key)來訪問類屬性的機(jī)制。而不是通...
    153037c65b0c閱讀 11,517評(píng)論 15 17
  • 前言:往往會(huì)某項(xiàng)工具WORK,就想究其原理。本文先簡單介紹KVC 一、KVC 簡介 1.1 KVC 概述 1.KV...
    夢蕊dream閱讀 937評(píng)論 0 2
  • 什么是KVC? KVC(Key-value coding)鍵值編碼,單看這個(gè)名字可能不太好理解。其實(shí)是指iOS的開...
    薩繆閱讀 4,687評(píng)論 1 13