KVO, KVC詳解

KVC/KVO是觀(guān)察者模式的一種實(shí)現(xiàn)蚁滋,在Cocoa中是以被萬(wàn)物之源NSObject類(lèi)實(shí)現(xiàn)的NSKeyValueCoding/NSKeyValueObserving非正式協(xié)議的形式被定義為基礎(chǔ)框架的一部分。從協(xié)議的角度來(lái)說(shuō)赵讯,KVC/KVO本質(zhì)上是定義了一套讓我們?nèi)プ袷睾蛯?shí)現(xiàn)的方法。

當(dāng)然您没,KVC/KVO實(shí)現(xiàn)的根本是Objective-C的動(dòng)態(tài)性和runtime温算,另外,KVC/KVO機(jī)制離不開(kāi)訪(fǎng)問(wèn)器方法的實(shí)現(xiàn)鹿驼,這在后文中也有解釋欲低。

KVO詳解

該類(lèi)必須支持KVC,使用屬性的 setter getter 方法畜晰,或 key-path砾莱;(需要實(shí)現(xiàn)與該屬性對(duì)應(yīng)的getter 和 setter 方法和其他一些可選的方法。NSObject類(lèi)已經(jīng)幫我們實(shí)現(xiàn)了這些凄鼻,只要你的類(lèi)繼承自NSObject腊瑟,并且使用正常方式創(chuàng)建屬性聚假,這些屬性都是支持KVO的;(實(shí)例變量 檢測(cè)不到變化))

KVO通知發(fā)出方式分為“手動(dòng)”和“自動(dòng)”兩種方式闰非;

  • 自動(dòng):自動(dòng)通知由NSObject默認(rèn)實(shí)現(xiàn)了膘格,一般情況下不需要我們寫(xiě)額外代碼,屬性改變后通知自動(dòng)發(fā)出财松;
  • 手動(dòng):可自行控制瘪贱,重寫(xiě)該方法(NSObject類(lèi)目方法)
+ (BOOL)automaticallyNotifiesObserversForKey:(NSString *)theKey;

可控制具體針對(duì)哪些屬性辆毡;

網(wǎng)上好多說(shuō)手動(dòng)實(shí)現(xiàn)菜秦,需要寫(xiě)下面兩個(gè)方法,但是實(shí)際代碼驗(yàn)證過(guò)程發(fā)現(xiàn)舶掖,不寫(xiě)也沒(méi)事球昨;

- (void)willChangeValueForKey:(NSString *)key;
- (void)didChangeValueForKey:(NSString *)key;

有時(shí)候會(huì)存在這樣一種情況,一個(gè)屬性的改變依賴(lài)于別的一個(gè)或多個(gè)屬性的改變眨攘,也就是說(shuō)當(dāng)別的屬性改了主慰,這個(gè)屬性也會(huì)發(fā)出通知
需要我們重寫(xiě)下面方法:
// 當(dāng) B 或 C 屬性變化時(shí),A屬性也會(huì)發(fā)出通知并監(jiān)聽(tīng)到(依賴(lài)鍵)

+ (NSSet *)keyPathsForValuesAffectingValueForKey:(NSString *)key {
       NSSet *keyPaths = [super keyPathsForValuesAffectingValueForKey:key];
       if ([key isEqualToString:@“A”]) {
            NSArray *affectingKeys = @[@“B”,@“C”];
            keyPaths = [keyPaths setByAddingObjectsFromArray: affectingKeys]鲫售;
       }
       return keyPaths;
}
  • KVO是基于runtime 實(shí)現(xiàn)的共螺;
  • 當(dāng)某個(gè)類(lèi)的屬性被第一次觀(guān)察時(shí),系統(tǒng)會(huì)在運(yùn)行期動(dòng)態(tài)的創(chuàng)建該類(lèi)的一個(gè)派生類(lèi)龟虎,在這個(gè)派生類(lèi)中重寫(xiě)基類(lèi)中任何被觀(guān)察屬性的setter方法璃谨。派生類(lèi)在被重寫(xiě)的setter方法內(nèi)實(shí)現(xiàn)真正的通知機(jī)制;
  • 如果原類(lèi)為 A鲤妥,那么生成的派生類(lèi)名為NSKVONotifying_A
    object_getClassName(“類(lèi)對(duì)象”) 獲取到 NSKVONotifying_A 類(lèi)名
  • 每個(gè)類(lèi)對(duì)象(類(lèi)的實(shí)例)都有一個(gè)isa指針 指向當(dāng)前類(lèi)佳吞,當(dāng)一個(gè)類(lèi)對(duì)象的第一次被觀(guān)察,系統(tǒng)會(huì)將isa指針指向動(dòng)態(tài)生成的派生類(lèi)棉安,從而給被監(jiān)控屬性賦值時(shí)執(zhí)行派生類(lèi)的setter方法底扳;(參考3)

當(dāng)手動(dòng)創(chuàng)建時(shí):系統(tǒng)會(huì)發(fā)出下面警告
KVO failed to allocate class pair for name NSKVONotifying_LabColor, automatic key-value observing will not work for this class

詳解KVC

NSKeyValueCoding:一種通過(guò)名稱(chēng)或鍵 間接訪(fǎng)問(wèn)對(duì)象屬性或者給對(duì)象賦值的機(jī)制,而不需要明確的存取方法贡耽。這樣就可以在運(yùn)行時(shí)動(dòng)態(tài)在訪(fǎng)問(wèn)和修改對(duì)象的屬性衷模。
NSObject 的類(lèi)目方法。所有繼承自 NSObject的都支持KVC 這個(gè)機(jī)制蒲赂;

KVC是怎么尋找Key的阱冶?
例如:personal類(lèi) name屬性

setter

1、程序優(yōu)先調(diào)用屬性 set 方法滥嘴,代碼通過(guò) setter 方法完成設(shè)置木蹬。
2、如果沒(méi)有找到 setName:方法若皱,KVC機(jī)制會(huì)檢查镊叁,該方法

+(BOOL)accessInstanceVariablesDirectly 

方法有沒(méi)有返回YES尘颓,默認(rèn)會(huì)返回YES,則這個(gè)時(shí)候KVC機(jī)制會(huì)搜索該類(lèi)里有沒(méi)有命名為“_name”晦譬、“_isName”疤苹、“name”、“isName”敛腌,
的成員變量卧土,

"_%s"、"_is%s"像樊、"%s"夸溶、"is%s"
無(wú)論該變量是在接口類(lèi)定義還是在類(lèi)的實(shí)現(xiàn)部分定義,也無(wú)論用了什么訪(fǎng)問(wèn)修飾符凶硅,KVC都會(huì)對(duì)該成員變量進(jìn)行操作。當(dāng)既沒(méi)有setter方法扫皱,沒(méi)有屬性足绅、也沒(méi)有上述成員變量時(shí),程序會(huì)走下面這個(gè)函數(shù)

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

3韩脑、當(dāng)重寫(xiě)+(BOOL)accessInstanceVariablesDirectly函數(shù)并返回NO時(shí)氢妈,那么只要沒(méi)有該屬性時(shí),即使聲明了相關(guān)的成員變量段多,也會(huì)執(zhí)行該setValue: forUndefinedKey:函數(shù)首量;

GET 搜索模式

1、 這是valueForKey:的默認(rèn)實(shí)現(xiàn)进苍,給定一個(gè)key當(dāng)做輸入?yún)?shù)加缘,開(kāi)始下面的步驟,在這個(gè)接收valueForKey:方法調(diào)用的類(lèi)內(nèi)部進(jìn)行操作觉啊。

通過(guò)getter方法搜索實(shí)例拣宏,例如get, , is, _的拼接方案。按照這個(gè)順序杠人,如果發(fā)現(xiàn)符合的方法勋乾,就調(diào)用對(duì)應(yīng)的方法并拿著結(jié)果跳轉(zhuǎn)到第五步。否則嗡善,就繼續(xù)到下一步辑莫。

2、 如果沒(méi)有找到簡(jiǎn)單的getter方法罩引,則搜索其匹配模式的方法countOf各吨、objectInAtIndex:、AtIndexes:蜒程。

如果找到其中的第一個(gè)和其他兩個(gè)中的一個(gè)绅你,則創(chuàng)建一個(gè)集合代理對(duì)象伺帘,該對(duì)象響應(yīng)所有NSArray的方法并返回該對(duì)象。否則忌锯,繼續(xù)到第三步伪嫁。

代理對(duì)象隨后將NSArray接收到的countOf、objectInAtIndex:偶垮、AtIndexes:的消息給符合KVC規(guī)則的調(diào)用方张咳。
當(dāng)代理對(duì)象和KVC調(diào)用方通過(guò)上面方法一起工作時(shí),就會(huì)允許其行為類(lèi)似于NSArray一樣似舵。

3脚猾、如果沒(méi)有找到NSArray簡(jiǎn)單存取方法,或者NSArray存取方法組砚哗。則查找有沒(méi)有countOf龙助、enumeratorOf、memberOf:命名的方法蛛芥。

如果找到三個(gè)方法提鸟,則創(chuàng)建一個(gè)集合代理對(duì)象(NSKeyValueSet),該對(duì)象響應(yīng)所有NSSet方法并返回仅淑。否則称勋,繼續(xù)執(zhí)行第四步。

此代理對(duì)象隨后轉(zhuǎn)換countOf涯竟、enumeratorOf赡鲜、memberOf:方法調(diào)用到創(chuàng)建它的對(duì)象上。實(shí)際上庐船,這個(gè)代理對(duì)象和NSSet一起工作银酬,使得其表象上看起來(lái)是NSSet。

4筐钟、如果沒(méi)有發(fā)現(xiàn)簡(jiǎn)單getter方法捡硅,或集合存取方法組,以及接收類(lèi)方法accessInstanceVariablesDirectly是返回YES的盗棵。搜索一個(gè)名為_(kāi)壮韭、_is、纹因、is的實(shí)例喷屋,根據(jù)他們的順序。
如果發(fā)現(xiàn)對(duì)應(yīng)的實(shí)例瞭恰,則立刻獲得實(shí)例可用的值并跳轉(zhuǎn)到第五步屯曹,否則,跳轉(zhuǎn)到第六步。

5恶耽、如果取回的是一個(gè)對(duì)象指針密任,則直接返回這個(gè)結(jié)果。
如果取回的是一個(gè)基礎(chǔ)數(shù)據(jù)類(lèi)型偷俭,但是這個(gè)基礎(chǔ)數(shù)據(jù)類(lèi)型是被NSNumber支持的浪讳,則存儲(chǔ)為NSNumber并返回。
如果取回的是一個(gè)不支持NSNumber的基礎(chǔ)數(shù)據(jù)類(lèi)型涌萤,則通過(guò)NSValue進(jìn)行存儲(chǔ)并返回淹遵。

6、如果所有情況都失敗负溪,則調(diào)用valueForUndefinedKey:方法并拋出異常透揣,這是默認(rèn)行為。但是子類(lèi)可以重寫(xiě)此方法川抡。

關(guān)于nil值的處理

(1)如果屬性基本類(lèi)型是(int辐真、float、double)且傳入對(duì)應(yīng)的參數(shù)崖堤,如果value設(shè)置一個(gè)nil拆祈,就會(huì)發(fā)生異常。
(2)可通過(guò)重寫(xiě)-(void)setNilValueForKey:(NSString *)key系統(tǒng)函數(shù)倘感,來(lái)做相關(guān)異常處理;

KVC 集合運(yùn)算符

  • Simple Collection Operators 簡(jiǎn)單的集合操作符
  • Object Operators 對(duì)象操作符
  • Array and Set Operators 數(shù)組/集合操作符

1咙咽、@count 返回一個(gè)值為集合中對(duì)象總數(shù)的NSNumber對(duì)象;
2老玛、@avg 首先把集合中的每個(gè)對(duì)象都轉(zhuǎn)換為double類(lèi)型,然后計(jì)算其平均值,并返回這個(gè)平均值的NSNumber對(duì)象;
3、@max 使用compare:方法來(lái)確定最大值,并返回最大值的NSNumber對(duì)象.所以為了保證其正常比較,集合中所有的對(duì)象都必須支持和另一個(gè)對(duì)象的比較,保證其可比性;
4钧敞、@min 原理和@max一樣,其返回的是集合中的最小值的NSNumber對(duì)象;
5蜡豹、@sum 首先把集合中的每個(gè)對(duì)象都轉(zhuǎn)換為double類(lèi)型,然后計(jì)算其總和,并返回總和的NSNumber對(duì)象;

Simple Collection Operators 簡(jiǎn)單的集合操作符

 // kvc 集合操作(基本數(shù)據(jù)類(lèi)型)
    KVCCollectionOperatorsTest *collectionTest = [[KVCCollectionOperatorsTest alloc] init];
    collectionTest.name = @"測(cè)試1";
    collectionTest.count = 10;
    
    KVCCollectionOperatorsTest *collectionTest2 = [[KVCCollectionOperatorsTest alloc] init];
    collectionTest2.name = @"測(cè)試2";
    collectionTest2.count = 20;
    
    KVCCollectionOperatorsTest *collectionTest3 = [[KVCCollectionOperatorsTest alloc] init];
    collectionTest3.name = @"測(cè)試3";
    collectionTest3.count = 30;

    NSArray *collectionArr = @[collectionTest, collectionTest2, collectionTest3];
    NSNumber *countNum = [collectionArr valueForKeyPath:@"@count"];
    NSNumber *avgNum = [collectionArr valueForKeyPath:@"@avg.count"];
    NSNumber *maxNum = [collectionArr valueForKeyPath:@"@max.count"];
    NSNumber *minNum = [collectionArr valueForKeyPath:@"@min.count"];
    NSNumber *sunNum = [collectionArr valueForKeyPath:@"@sum.count"];

    // 若操作對(duì)象(數(shù)組/集合)內(nèi)的元素本身就是 NSNumber 對(duì)象,那么可以這樣寫(xiě).
    NSArray *collectionArr2 = @[@(collectionTest.count), @(collectionTest2.count), @(collectionTest3.count)];
    NSNumber *countNum2 = [collectionArr2 valueForKeyPath:@"@count"];
    NSNumber *avgNum2 = [collectionArr2 valueForKeyPath:@"@avg.self"];
    NSNumber *maxNum2 = [collectionArr2 valueForKeyPath:@"@max.self"];
    NSNumber *minNum2 = [collectionArr2 valueForKeyPath:@"@min.self"];
    NSNumber *sunNum2 = [collectionArr2 valueForKeyPath:@"@sum.self"];

Object Operators 對(duì)象操作符

  • @unionOfObjects: 獲取數(shù)組中每個(gè)對(duì)象的屬性的值,放到一個(gè)數(shù)組中并返回,但不會(huì)去重;
  • @distinctUnionOfObjects:獲取數(shù)組中每個(gè)對(duì)象的屬性的值,放到一個(gè)數(shù)組中并返回,會(huì)對(duì)數(shù)組去重.所以,通常這個(gè)對(duì)象操作符可以用來(lái)對(duì)數(shù)組元素的去重,快捷高效;
    NSArray *unionOfObjects = [collectionArr valueForKeyPath:@"@unionOfObjects.name"];
    NSArray *distinctUnionOfObjects = [collectionArr valueForKeyPath:@"@distinctUnionOfObjects.name"];
    NSLog(@"unionOfObjects = %@",unionOfObjects);
    NSLog(@"distinctUnionOfObjects = %@",distinctUnionOfObjects);

// 輸出
2018-04-16 16:59:11.891950+0800 KVODemo[8751:365605] unionOfObjects = (
    aaa,
    bbb,
    aaa
)
2018-04-16 16:59:12.791130+0800 KVODemo[8751:365605] distinctUnionOfObjects = (
    aaa,
    bbb
)

Array and Set Operators 數(shù)組和集合操作符
數(shù)組和集合操作符作用對(duì)象是嵌套的集合,也就是說(shuō)溉苛,是一個(gè)集合且其內(nèi)部每個(gè)元素是一個(gè)集合镜廉。數(shù)組和集合操作符包括 @distinctUnionOfArrays@unionOfArrays愚战,@distinctUnionOfSets:

  • @distinctUnionOfArrays娇唯、@unionOfArrays返回一個(gè)數(shù)組,其中包含這個(gè)集合中每個(gè)數(shù)組對(duì)于這個(gè)操作符右面指定的 keyPath 進(jìn)行操作之后的值寂玲。distinct 會(huì)移除重復(fù)的值塔插。
  • @distinctUnionOfSets@distinctUnionOfArrays差不多,但是它期望的是一個(gè)包含著NSSet對(duì)象的NSSet拓哟,并且會(huì)返回一個(gè)NSSet對(duì)象想许。因?yàn)榧喜荒馨貜?fù)的值,所以只有distinct操作;
    /*
     數(shù)組和集合操作符
     * @distinctUnionOfArrays:
     * @unionOfArrays:
     * @distinctUnionOfSets:
     */
    KVCCollectionOperatorsTest *arrAndSetTest = [[KVCCollectionOperatorsTest alloc] init];
    arrAndSetTest.name = @"aaa";
    arrAndSetTest.count = 10;
    
    KVCCollectionOperatorsTest *arrAndSetTest2 = [[KVCCollectionOperatorsTest alloc] init];
    arrAndSetTest2.name = @"bbb";
    arrAndSetTest2.count = 20;
    
    KVCCollectionOperatorsTest *arrAndSetTest3 = [[KVCCollectionOperatorsTest alloc] init];
    arrAndSetTest3.name = @"aaa";
    arrAndSetTest3.count = 30;
    
    
    KVCCollectionOperatorsTest *arrAndSetTest4 = [[KVCCollectionOperatorsTest alloc] init];
    arrAndSetTest4.name = @"arrAndSetTest";
    arrAndSetTest4.count = 10;
    
    KVCCollectionOperatorsTest *arrAndSetTest5 = [[KVCCollectionOperatorsTest alloc] init];
    arrAndSetTest5.name = @"arrAndSetTest2";
    arrAndSetTest5.count = 20;
    
    KVCCollectionOperatorsTest *arrAndSetTest6 = [[KVCCollectionOperatorsTest alloc] init];
    arrAndSetTest6.name = @"arrAndSetTest3";
    arrAndSetTest6.count = 30;
    
    NSArray *arrayAndSetCollectionArr = @[arrAndSetTest, arrAndSetTest2, arrAndSetTest3];
    NSArray *arrayAndSetCollectionArr2 = @[arrAndSetTest4, arrAndSetTest5, arrAndSetTest6];

    NSMutableArray *totalCount = [NSMutableArray array];
    [totalCount addObject:arrayAndSetCollectionArr];
    [totalCount addObject:arrayAndSetCollectionArr2];
    
    NSLog(@"--- %@",[totalCount valueForKeyPath:@"@unionOfArrays.name"]);
    NSLog(@"+++ %@",[totalCount valueForKeyPath:@"@distinctUnionOfArrays.name"]);


輸出
2018-04-17 10:23:41.399298+0800 KVODemo[1280:55204] --- (
    aaa,
    bbb,
    aaa,
    arrAndSetTest,
    arrAndSetTest2,
    arrAndSetTest3
)
2018-04-17 10:23:41.936263+0800 KVODemo[1280:55204] +++ (
    bbb,
    aaa,
    arrAndSetTest,
    arrAndSetTest2,
    arrAndSetTest3
)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末流纹,一起剝皮案震驚了整個(gè)濱河市糜烹,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌漱凝,老刑警劉巖疮蹦,帶你破解...
    沈念sama閱讀 217,185評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異碉哑,居然都是意外死亡挚币,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門(mén)扣典,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)妆毕,“玉大人,你說(shuō)我怎么就攤上這事贮尖〉颜常” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,524評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵湿硝,是天一觀(guān)的道長(zhǎng)薪前。 經(jīng)常有香客問(wèn)我,道長(zhǎng)关斜,這世上最難降的妖魔是什么示括? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,339評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮痢畜,結(jié)果婚禮上垛膝,老公的妹妹穿的比我還像新娘。我一直安慰自己丁稀,他們只是感情好吼拥,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,387評(píng)論 6 391
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著线衫,像睡著了一般凿可。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上授账,一...
    開(kāi)封第一講書(shū)人閱讀 51,287評(píng)論 1 301
  • 那天枯跑,我揣著相機(jī)與錄音,去河邊找鬼白热。 笑死全肮,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的棘捣。 我是一名探鬼主播辜腺,決...
    沈念sama閱讀 40,130評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼休建,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了评疗?” 一聲冷哼從身側(cè)響起测砂,我...
    開(kāi)封第一講書(shū)人閱讀 38,985評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎百匆,沒(méi)想到半個(gè)月后砌些,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,420評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡加匈,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,617評(píng)論 3 334
  • 正文 我和宋清朗相戀三年存璃,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片雕拼。...
    茶點(diǎn)故事閱讀 39,779評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡纵东,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出啥寇,到底是詐尸還是另有隱情偎球,我是刑警寧澤,帶...
    沈念sama閱讀 35,477評(píng)論 5 345
  • 正文 年R本政府宣布辑甜,位于F島的核電站衰絮,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏磷醋。R本人自食惡果不足惜猫牡,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,088評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望邓线。 院中可真熱鬧淌友,春花似錦、人聲如沸褂痰。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,716評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)缩歪。三九已至,卻和暖如春谍憔,著一層夾襖步出監(jiān)牢的瞬間匪蝙,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,857評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工习贫, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留逛球,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,876評(píng)論 2 370
  • 正文 我出身青樓苫昌,卻偏偏與公主長(zhǎng)得像颤绕,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,700評(píng)論 2 354

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

  • KVC(Key-value coding)鍵值編碼奥务,單看這個(gè)名字可能不太好理解物独。其實(shí)翻譯一下就很簡(jiǎn)單了,就是指iO...
    黑暗中的孤影閱讀 49,724評(píng)論 74 441
  • KVC(Key-valuecoding)鍵值編碼氯葬,單看這個(gè)名字可能不太好理解挡篓。其實(shí)翻譯一下就很簡(jiǎn)單了,就是指iOS...
    榕樹(shù)頭閱讀 711評(píng)論 0 2
  • KVC(Key-value coding)鍵值編碼帚称,單看這個(gè)名字可能不太好理解官研。其實(shí)翻譯一下就很簡(jiǎn)單了,就是指iO...
    Fendouzhe閱讀 674評(píng)論 0 6
  • KVO屬性依賴(lài) 看一個(gè)例子:我們的模型類(lèi) LabColor 代表一種 lab色彩空間里的顏色。和 RGB 不同瞻坝,這...
    毅個(gè)天亮閱讀 755評(píng)論 0 1
  • 前言: 本文基本不講KVC/KVO的用法蛛壳,只結(jié)合網(wǎng)上的資料說(shuō)說(shuō)對(duì)這種技術(shù)的理解。 由于KVO內(nèi)容較少所刀,而且是以KV...
    土b蘭博王閱讀 3,062評(píng)論 0 33