定義: ?把字典中的數(shù)據使用模型來保存。新建一個類,根據字典中鍵值對,來編寫這個類中的屬性,將來用這個類的對象的屬性來保存字典中每個鍵對應的值恨课。
為什么要用字典去轉模型:
0>寫代碼的時候字典的鍵沒有智能提示,但是模型的屬性可以有智能提示
1>"鍵"是字符串,如果寫錯了,編譯器不報錯(在編譯的時候不報錯),運行時可能出錯,出錯了很難找錯编曼。
2>使用"模型"可以更方便的使用面向對象的3大特(封裝唐瀑、繼承谈宛、多態(tài))性進行擴展鸽照。
3>將來的這個"模型"可能會在很多地方被用到(比如有很多個控制器都會使用這個模型),那么每次用到模型的地方都需要寫一次把字典中的數(shù)據賦給模型屬性的代碼,此時如果把這些賦值語句封裝到模型內部,會大大簡化了使用復雜度與代碼量户秤。
字典轉模型需要修改哪里的代碼:
1>創(chuàng)建一個模型類
2>在懶加載數(shù)據的時候,(或者網絡請求數(shù)據后)把加載到的數(shù)據都放到模型對象中,然后再把模型對象放到數(shù)組中码秉。
KVC: (鍵值編碼)
定義: 在對象創(chuàng)建完成之后,動態(tài)(牽扯到運行時)的給對象的屬性賦值
KVC,即是指 NSKeyValueCoding鸡号,一個非正式的Protocol转砖,提供一種機制來間接訪問對象的屬性。而不是通過調用Setter鲸伴、Getter方法訪問府蔗。
在OC的API中:
@interfaceNSObject(NSKeyValueCoding) ?// 非正式協(xié)議
@end
用法:
1>基本取值賦值
賦值: ?[對象:setValue:forkey:]
fu值:[對象:valueforKey]
2> 因為類key反復嵌套,所以有個keyPath的概念汞窗,keyPath就是用.號來把一個一個key鏈接起來姓赤,這樣就可以根據這個路徑訪問下去
3>KVC還有一個很重要的特點,自動裝箱拆箱功能杉辙。這在ObjC中是僅有的模捂,其他情況下均需要使用比如NSNumber來手動拆裝箱的捶朵。
裝箱:把值類型轉換成引用類型 ?若是int 轉換成NSNumer或者NSString
拆箱:將引用類型轉換成值類型 ?與上面想反
4> KVC 還可以對NSArray和NSSet 進行賦值
5> 通過字典去進行賦值(不要忘了重寫那個方法)
[對象setValuesForKeysWithDictionary:dict]
// 若對象沒有值
- (void)setValue:(id)value forUndefinedKey:(NSString *)key
6> 在運行時給私有屬性或者可讀屬性進行賦值
//注意:(解檔和歸檔的方法不是KVC,而是NSCoding這個協(xié)議)
@protocolNSCoding
- (void)encodeWithCoder:(NSCoder*)aCoder;
- (nullableinstancetype)initWithCoder:(NSCoder*)aDecoder;
@end
KVO:(鍵值監(jiān)聽)
2、KVO的是KeyValue Observe的縮寫狂男,中文是鍵值觀察综看。這是一個典型的觀察者模式,觀察者在鍵值改變時會得到通知岖食。iOS中有個Notification的機制红碑,也可以獲得通知,但這個機制需要有個Center泡垃,相比之下KVO更加簡潔而直接析珊。
KVO的使用也很簡單,就是簡單的3步蔑穴。
注冊需要觀察的對象的屬性addObserver:forKeyPath:options:context:
實現(xiàn)observeValueForKeyPath:ofObject:change:context:方法忠寻,這個方法當觀察的屬性變化時會自動調用
取消注冊觀察removeObserver:forKeyPath:context:
KVO:IOS里面的黑魔法,建議不要過多的使用,因為他的模式是一種輪詢的方式,比如,一直在敲門,直到打開門為止,還有一種采用輪訓的方式的是多線程中的自旋鎖.
KVO 代碼示例:
@interfacemyPerson:NSObject
{
NSString*_name;
int_age;
int_height;
int_weight;
}
@end
@interfacetestViewController:UIViewController
@property(nonatomic,?retain)?myPerson?*testPerson;
-?(IBAction)onBtnTest:(id)sender;
@end
-?(void)testKVO
{
testPerson?=?[[myPerson?alloc]?init];
[testPerson?addObserver:selfforKeyPath:@"height"options:NSKeyValueObservingOptionNewcontext:nil];
}
-?(void)observeValueForKeyPath:(NSString*)keyPath?ofObject:(id)object?change:(NSDictionary*)change?context:(void*)context
{
if([keyPath?isEqualToString:@"height"])?{
NSLog(@"Height?is?changed!?new=%@",?[change?valueForKey:NSKeyValueChangeNewKey]);
}else{
[superobserveValueForKeyPath:keyPath?ofObject:object?change:change?context:context];
}
}
-?(IBAction)onBtnTest:(id)sender?{
inth?=?[[testPerson?valueForKey:@"height"]?intValue];
[testPerson?setValue:[NSNumbernumberWithInt:h+1]?forKey:@"height"];
NSLog(@"person?height=%@",?[testPerson?valueForKey:@"height"]);
}
-?(void)dealloc
{
[testPerson?removeObserver:selfforKeyPath:@"height"context:nil];
[superdealloc];
}
自旋鎖:
互斥鎖:
多個線程共享同一個資源時,會造成線程不安全解決方式 互斥鎖
主要是防止多線程搶資源造成的數(shù)據不安全
原理 :每一個對象(NSObject)內部都有一個鎖(變量)當有線程要進入synchronized到代碼塊的時候先檢查對象的鎖是打開或者是關閉默認是打開,當線程會進入代碼的內部,進行上鎖
如果鎖是是關閉的,再有線程執(zhí)行代碼的時候就要先等待,直到上個線程結束后就先等待,直到直到鎖打開就才可以執(zhí)行
@synchronized(self) {// 需要鎖定的代碼} 注意self要是全局對象
atomic :自旋鎖??(單寫多寫) 效率低 (輪訊)
1.使用id作為方法返回值的問題:
1>在接收方法的返回值的時候可以使用任何類型來接收,編譯都不報錯,但是運行時可能出錯。
2.instancetype需要注意的點
1>instancetype在類型表示上,與id意思一樣,都表示任何對象類型
2>instancetype只能用作返回值類型,不能向id一樣聲明變量存和、用作參數(shù)等
3>使用instancetype,編譯器會檢測instancetype的真實類型,如果類型不匹配,編譯時會有個警告(Incompatible pointer types returning 'Person *' from a function with result type 'BFButton *’ 不相容的指針類型“人*”從函數(shù)返回結果類型“BFButton *”)奕剃。(instancetype出現(xiàn)在哪個類型中就表示對應的類型)