程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> object-c編程tips-jastor自動解析

object-c編程tips-jastor自動解析

編輯:關於C語言

object-c編程tips-jastor自動解析


前言

過去寫iphone程序一直都沒有用過自動解析,都是手動按著字典一層一層的解析,這樣費時費力,還容易出錯。後來公司來了新朋友帶來了自動解析的jastor庫,著實不錯。

簡單介紹一下jastor

jastor是一個基於oc運行時的庫,它可以將字典對象轉換成NSObject對象。它支持NSString, NSNumber,NSArray, NSDictionary以及它們的嵌套類型。例如現在需要將dict轉換為model。 dict為NSDictionary對象, model為繼承於Jastor的NSObject對象。 Jastor通過遍歷model對象的所有屬性, 以屬性作的名字作為dict的key,得到字典的value值。 然後根據value值的類型,進行不同的處理。 如果value是NSArray類型,那麼就進入NSArray的解析流程; 如果value是NSDictionary類型,那麼開始進行遞歸調用,如果是其他普通類型,則直接setvalue:forKey。當進入NSArray的處理流程時候,調用類的“屬性_class”方法獲取到數組對象的類型,然後對數組對象進行逐步解析,數組對象也必須是字典類型。

為什麼寫這篇博客?

Jastor確實可以大大簡化代碼的解析流程,當然效率肯定沒有手動解析的效率高,這個可以從代碼的遞歸流程以及使用Runtime的各種遍歷方法中可以看出。 但是作為開發人員,這麼點的效率損失可以帶來大量代碼的簡潔,減少開發人員的出錯幾率,它的益處是顯而易見的。當第一次使用Jastor時候,著實為它的代碼的簡潔所吸引,主要的有遞歸解析思想,rumtime的相關內容, 組合模式,緩存機制。後來加入到代碼中後,總會有一些崩潰的情況,主要是一些容錯性的問題,畢竟我們沒有辦法要求服務器下發的json數據每次都是和我們要求的一直,總有一些不一致的情況引起意想不到的問題。

Jastor遞歸解析

Jastor本身是一個基類,它可以將字典轉換成model, 如果字典的某一個成員又是字典,那麼它可以遞歸進去繼續解析,直到遇到的是一個普通的單一數據類型例如NSString,NSNumber等等為止,通過這樣層層的遞歸,深入到最裡層後也就是Jastor解析的結束。它通過for循環遍歷當前類的所有屬性,逐一尋找屬性在字典裡面的value值,根據value值的不同類型以及屬性的類型決定下一步進行遞歸解析還是直接setValueForKey。

            if ([dictOrArray isKindOfClass:nsDictionaryClass]) {
                value = [dictOrArray valueForKey:jsonKey];
                
                if (value == [NSNull null] || value == nil) {
                    continue;
                }
                
                if ([JastorRuntimeHelper isPropertyReadOnly:[self class] propertyName:classAttrName]) {
                    continue;
                }
                
                // handle dictionary
                if ([value isKindOfClass:nsDictionaryClass]) {
                    Class klass = [JastorRuntimeHelper propertyClassForPropertyName:classAttrName ofClass:[self class]];
                    if (![klass isSubclassOfClass:[Jastor class]]) {
                        NSLog(@"服務器返回的數據類型和客戶端不一致");
                        continue;
                    }
                    value = [[[klass alloc] initWithDictOrArray:value] autorelease];
                }
                // handle array
                else if ([value isKindOfClass:nsArrayClass]) {
                    value = [self dealWithArrayValue:value attrName:classAttrName jsonKey:jsonKey];
                }
                // handle nsnumber
                else if([value isKindOfClass:[NSNumber class]]){
                    value = [(NSNumber *)value stringValue];
                }

            }

請看上面的代碼,當傳入的是dict的時候,會進入到此if流程中, 首先判斷value是否為空,如果為空,直接跳過;然後判斷屬性是只讀,只讀也直接跳過;然後判斷value是字典的情況,如果是字典進行遞歸深入;然後判斷是數組的情況,數組進行數組元素的遍歷解析,最後判斷是NSNumber,得到NSNumber的string值。 得到最後的value後,會進行如下的操作

            // handle all others
            if (value) {
                [self setValue:value forKey:classAttrName];
            }

Jastor的Runtime

Runtime用的比較好, 其實裡面也就幾個方法而已,不過由於用的比較少,可能感覺它有些高大上了,其實仔細看看,也是普通的屬性遍歷而已。總共就幾個方法: 判斷屬性是否可讀,獲取一個類對象的所有屬性列表數組,判斷指定類對象的給定屬性的類型。所有的方法基於一個基本的思想: 遍歷類對象的所有objc_property_t的屬性進行處理。 這裡面效率肯定比較低,但是這裡面作者用了緩存的思想,無緩沖就遍歷並寫入緩存,下次直接讀緩存。

Jastor的組合模式

派生類的model繼承於Jastor,派生類model的某一個屬性可能也繼承於Jastor。一個大的model是一堆Jastor的子類的組合, 通過這種類似於組合模式的思想,貫穿到遞歸數據解析中,只是通常的組合模式不是類和屬性的組合,而且集合和單品元素的組合,其實原理的精髓是一樣的。

Jastor的緩存機制

可以看到裡面有各種緩存,包括獲取屬性列表,是否可讀,獲取指定屬性的類對象,獲取常用類的類對象等等,都進行的緩存操作,只用了幾個簡簡單單的字典,卻可以大大提高程序的執行效率,相當不錯。

Jastor的容錯性

Jastor本身已經進行了各種容錯,不過對於應用來說還是有些缺陷的,畢竟程序可以出錯,但不可以崩潰,這是一個基本准則。因此,我主要通過猜,試驗,發現了幾個崩潰點,和同事一起進行了修正,加入了幾個容錯,至少在我們的應用中,並沒有出現崩潰的情況。

Jastor的map特性

新版的Jastor加入了map,屬性名稱可以任意,賦予程序以最大的靈活性。原來我們使用的這一版沒有這種內容,我們組的牛人波波同志加入了map機制,剛開始我感覺必要性不是很大,但是隨著後期的項目的推進,確實用處極大。


對於Jastor,代碼我就不貼了,Github有庫,GitHub地址。 對於Jastor出現崩潰的情況,一定要跟進Jastor裡面,找到問題,加入保護即可。






  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved