iOS小技能之字典轉(zhuǎn)模及對(duì)象相等性示例詳解
前言
字典轉(zhuǎn)模型
/** 通常實(shí)現(xiàn)字典實(shí)例化模型,都實(shí)現(xiàn)了以下模型的實(shí)例化方法*/ //使用字典實(shí)例化模型 - (instancetype) initWithDictionary :(NSDictionary *) appDictionary; //類方法可以快速實(shí)例化一個(gè)對(duì)象--把代碼放在它最應(yīng)該呆的地方 + (instancetype) appInfoWithDictionary : (NSDictionary *) appDictionary; //返回plist文件對(duì)應(yīng)的模型數(shù)組 ,使用懶加載
KVC的賦值
- (instancetype) initWithDictionary:(NSDictionary *)appDictionary{ //self is object self = [super init]; if (self) {//既然nil解析成NO,所以沒有必要在條件語句比較。不要拿某樣?xùn)|西直接與YES比較,因?yàn)閅ES被定義為1 //init local vars 將plist文件的信息在此處進(jìn)行字典轉(zhuǎn)模型 //KVC (key value coding) 鍵值編碼:是一種間接修改、讀取對(duì)象屬性的一種方法;KVC被稱為cocoa的大招 [self setValuesForKeysWithDictionary:appDictionary];//本質(zhì)上是調(diào)用 self setValue:<#(nullable id)#> forUndefinedKey:(nonnull NSString *) } return self; }
I 字典轉(zhuǎn)模型
- 使用字典的壞處
通常取出和修改數(shù)據(jù)字典的數(shù)據(jù),都要通過編寫“字符串類型”的key值-》編輯器IDE沒有智能提示、手動(dòng)寫key容易寫錯(cuò),且此時(shí)IDE不會(huì)有任何的警告和報(bào)錯(cuò)。 字典的使用例子
dict[@"name"] = @"Jack"; NSString *name = dict[@"name"];
- 使用數(shù)據(jù)模型的好處
1)數(shù)據(jù)模型(專門用來存放數(shù)據(jù)的對(duì)象),使用數(shù)據(jù)模型表示數(shù)據(jù)更專業(yè)些
2)使用模型修改數(shù)據(jù)、讀取數(shù)據(jù)均采用對(duì)象的屬性,提高編寫效率
1.1 字典轉(zhuǎn)模型的實(shí)現(xiàn)步驟
1)字典轉(zhuǎn)模型的過程,通常被封裝在模型內(nèi)部
2)模型應(yīng)該提供一個(gè)“帶有NSDictionary類型”參數(shù)的構(gòu)造方法
- (instancetype)initWithDict:(NSDictionary*)dict; + (instancetype)xxxWithDict:(NSDictionary*)dict;
1.2 字典轉(zhuǎn)模型的過程
- [采用KVC(keyValueCoding)實(shí)現(xiàn)] plist文件解析-》字典數(shù)組(NSDictionary)-》模型數(shù)組(AppInfo)
使用字典實(shí)例化模型 (把代碼放在它最應(yīng)該呆的地方)
- (instancetype) initWithDictionary:(NSDictionary *)appDictionary{ //self is object self = [super init]; if (self) {//既然nil解析成NO,所以沒有必要在條件語句比較。不要拿某樣?xùn)|西直接與YES比較,因?yàn)閅ES被定義為1 //init local vars 將plist文件的信息在此處進(jìn)行字典轉(zhuǎn)模型 //KVC (key value coding) 鍵值編碼:是一種間接修改、讀取對(duì)象屬性的一種方法;KVC被稱為cocoa的大招 [self setValuesForKeysWithDictionary:appDictionary]; } return self; } //使用類方法實(shí)現(xiàn)“字典實(shí)例化模型”--地道的代碼 + (instancetype) appInfoWithDictionary:(NSDictionary *)appDictionary{ //self is class return [[self alloc]initWithDictionary:appDictionary];//+ (instancetype)alloc Description Returns a new instance of the receiving class. } @end
- 使用KVC的注意事項(xiàng):
1、plist文件中的鍵值名稱必須與模型對(duì)象的屬性名稱一致
2、模型中的屬性,可以不全部出現(xiàn)在plist文件中
II 對(duì)象的相等性 & 本體性
一個(gè)對(duì)象的本體和它的內(nèi)存地址是相關(guān)聯(lián)的。 NSObject 的isEqual:本質(zhì)上是對(duì)本體性的檢查,即兩個(gè) NSObject 如果指向了同一個(gè)內(nèi)存地址,那它們就被認(rèn)為是相同的。
當(dāng)兩個(gè)物體有一系列相同的可觀測(cè)的屬性時(shí),兩個(gè)物體可能是互相相等 。
2.1 相等性檢查
對(duì)象相等性檢查的主要應(yīng)用場(chǎng)景:確定一個(gè)對(duì)象是不是一個(gè)集合的成員,對(duì)于 NSArray,NSDictionary 和 NSString 容器類來說,更加有用的是進(jìn)行相等性檢查,即對(duì)于集合中的每個(gè)成員進(jìn)行判斷,因此我們需要重寫isEqual: 。
重寫 isEqual:
- 先進(jìn)行本體性檢查,如果失敗,就進(jìn)行實(shí)際內(nèi)容(意義)上的比較,比如判斷其中幾個(gè)主要特性的屬性。
- (BOOL)isEqual:(id)object { if (self == object) { return YES; } if (![object isKindOfClass:[Person class]]) { return NO; } return [self isEqualToPerson:(Person *)object];//關(guān)鍵屬性的判斷,比如身份證ID }
- 重寫 hash 方法,便于快速地(O(1)) 進(jìn)行元素查找。
相對(duì)于數(shù)組把元素按順序存儲(chǔ)(0, 1, ..., n-1),散列表在內(nèi)存中分配 n 個(gè)位置,然后使用一個(gè)散列函數(shù)來計(jì)算出位置范圍之內(nèi)的某個(gè)具體位置。
hash 得到的值不必是唯一可區(qū)分的,如果發(fā)生了散列碰撞,散列表會(huì)從碰撞產(chǎn)生的位置開始向后尋找,把新的元素放在第一個(gè)可供放置的位置。
@implementation NSDate (ex) - (NSUInteger)hash { return (NSUInteger)abs([self timeIntervalSinceReferenceDate]); }
對(duì)關(guān)鍵屬性的散列值進(jìn)行一個(gè)簡單的二進(jìn)制移位操作,即可簡單的實(shí)現(xiàn)對(duì)象的hash 函數(shù):
@implementation UIColor (ex) /** >左移運(yùn)算符(<<):按二進(jìn)制形式把所有的數(shù)字向左移動(dòng)對(duì)應(yīng)的位數(shù),高位移出(舍棄),低位的空位補(bǔ)零。 */ - (NSUInteger)hash { CGFloat red, green, blue; [self getRed:&red green:&green blue:&blue alpha:nil]; return ((NSUInteger)(red * 255) << 16) + ((NSUInteger)(green * 255) << 8) + (NSUInteger)(blue * 255); } @end
對(duì)關(guān)鍵屬性的散列值進(jìn)行一個(gè)簡單的XOR操作
/** 異或 ^ 相同為0,不相同為1; 應(yīng)用場(chǎng)景:密碼加密、散列值計(jì)算。 */ - (NSUInteger)hash { return [self.id hash] ^ [self.birthday hash]; }
2.2 Foundation 框架中,自己實(shí)現(xiàn)的相等性檢查
NSAttributedString -isEqualToAttributedString:
NSData -isEqualToData:
NSDate -isEqualToDate:
NSDictionary -isEqualToDictionary:
NSHashTable -isEqualToHashTable:
NSIndexSet -isEqualToIndexSet:
NSNumber -isEqualToNumber:
NSOrderedSet -isEqualToOrderedSet:
NSSet -isEqualToSet:
NSString -isEqualToString:
NSTimeZone -isEqualToTimeZone:
NSValue -isEqualToValue:
2.3 字符串駐留
字符串駐留的優(yōu)化技術(shù): 把一個(gè)不可變字符串對(duì)象的值拷貝給各個(gè)不同的指針。
Objective-C 選擇器的名字也是作為駐留字符串儲(chǔ)存在一個(gè)共享的字符串池當(dāng)中的。
NSString *stra = @"Hello"; NSString *strb = @"Hello"; BOOL wt = (stra == strb); // YES
選擇器的比較
OBJC_EXPORT BOOL class_respondsToSelector(Class _Nullable cls, SEL _Nonnull sel) OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); - (BOOL)respondsToSelector:(SEL)aSelector; if([device respondsToSelector:@selector(setSmoothAutoFocusEnabled:)]){ }
III 代碼重構(gòu)(前提是已經(jīng)實(shí)現(xiàn)了基本功能)
開發(fā)前:設(shè)定開發(fā)計(jì)劃、步驟 開發(fā)過程中:每一個(gè)步驟告一段落之后,我們要暫停,進(jìn)行代碼審核,有針對(duì)性的重構(gòu)(抽離重復(fù)代碼,模型和視圖各盡職責(zé))
代碼重構(gòu)的原則: 把代碼放在它最應(yīng)該呆的地方
1、使用類方法實(shí)現(xiàn)字典實(shí)例化模型 (模型,通常是plist文件,網(wǎng)絡(luò))
使用類方法實(shí)例化模型數(shù)組
//類方法可以快速實(shí)例化一個(gè)對(duì)象--把代碼放在它最應(yīng)該呆的地方 + (instancetype) appInfoWithDictionary : (NSDictionary *) appDictionary; //返回plist文件對(duì)應(yīng)的模型數(shù)組 ,使用懶加載 + (NSArray *)appList;
2、使用類方法實(shí)例化視圖對(duì)象,并用數(shù)據(jù)模型裝配視圖內(nèi)容
用類方法進(jìn)行視圖的實(shí)例化
+ (instancetype) appView;//使用類方法加載xib + (instancetype) appViewWithAppInfo:(KNAppInfo *) appInfo;//使用類方法加載xib,參數(shù)用于視圖的數(shù)據(jù)裝配
see also
更多內(nèi)容請(qǐng)關(guān)注 #小程序:iOS逆向,只為你呈現(xiàn)有價(jià)值的信息,專注于移動(dòng)端技術(shù)研究領(lǐng)域;
以上就是iOS小技能之字典轉(zhuǎn)模及對(duì)象相等性示例詳解的詳細(xì)內(nèi)容,更多關(guān)于iOS字典轉(zhuǎn)模對(duì)象相等性的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
iOS正則表達(dá)式驗(yàn)證手機(jī)號(hào)、郵箱、身份證號(hào)等
這篇文章主要介紹了iOS正則表達(dá)式驗(yàn)證手機(jī)號(hào)、郵箱、身份證號(hào)等信息,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-12-12iOS常用算法之兩個(gè)有序數(shù)組合并(要求時(shí)間復(fù)雜度為0(n))
這篇文章主要介紹了iOS常用算法之兩個(gè)有序數(shù)組合并(要求時(shí)間復(fù)雜度為0(n)),實(shí)現(xiàn)思路是先將一個(gè)數(shù)組作為合并后的數(shù)組, 然后遍歷第二個(gè)數(shù)組的每項(xiàng)元素,需要的朋友可以參考下2019-07-07iOS開發(fā)中Subview的事件響應(yīng)以及獲取subview的方法
這篇文章主要介紹了iOS開發(fā)中Subview的事件響應(yīng)以及獲取subview的方法,代碼基于傳統(tǒng)的Objective-C,需要的朋友可以參考下2015-09-09iOS CAEmitterLayer實(shí)現(xiàn)粒子發(fā)射動(dòng)畫效果
這篇文章主要為大家詳細(xì)介紹了iOS CAEmitterLayer 實(shí)現(xiàn)粒子發(fā)射動(dòng)畫效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-06-06iOS從App跳轉(zhuǎn)至系統(tǒng)設(shè)置菜單各功能項(xiàng)的編寫方法講解
這篇文章主要介紹了iOS從App跳轉(zhuǎn)至系統(tǒng)設(shè)置菜單各功能項(xiàng)的編寫方法講解,示例代碼為傳統(tǒng)的Objective-C,需要的朋友可以參考下2016-04-04IOS開發(fā)使用KeychainItemWrapper 持久存儲(chǔ)用戶名和密碼
這篇文章主要介紹了IOS開發(fā)使用KeychainItemWrapper 持久存儲(chǔ)用戶名和密碼的相關(guān)資料,需要的朋友可以參考下2015-11-11Objective-C的UIStackView常用屬性函數(shù)學(xué)習(xí)筆記
這篇文章主要為大家介紹了Objective-C的UIStackView常用屬性函數(shù)學(xué)習(xí)筆記,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03