json轉model,是個開發都會遇到過。都已經9102年了,誰還不會用個第三方框架搞。拿起鍵盤就是幹!json
啥?返回的字段值不是咱們所需的 在平常開發中,常常會遇到一些接口字段返回的值,並非我所須要的類型的狀況,這個時候,咱們都會對這個字段進行處理。 舉個栗子:bash
/** 錯誤代碼 */
@property (nonatomic, assign) NSInteger error_code;
/** 錯誤消息 */
@property (nonatomic, copy) NSString *error_msg;
/** 是否成功 */
@property (nonatomic, assign) BOOL isSuccess;
複製代碼
接口的json中的error_code字段,接口會用這個字段告訴我此次請求是否成功。比方說成功的error_code是1,平時咱們爲了方便開發,會在model裏本身加一個自定義的屬性isSuccess,來表示本次網絡請求回來以後的結果是否成功。一般的作法,要麼重寫error_code的set方法,在set的時候,作一次error_code==1的判斷,將判斷的結果,賦值給isSuccess,要麼就重寫isSuccess的get方法,get的時候,返回error_code==1的結果。 相信這些對於老司機們而言,都屬於常規操做了。那咱們來看看坑在什麼地方?網絡
咱們來看這個案例: 接口返回了4個字段值,每一個字段都用獲得,因此新建一個model類來解析。架構
@interface ExamSubjectVo : NSObject
/** 考試學科ID */
@property (nonatomic, assign) NSInteger examSubjectValue;
/** 考試學科名稱 */
@property (nonatomic, strong) NSString *examSubjectName;
/** 學科分數 */
@property (nonatomic, strong) NSString *subjectScore;
/** 基礎學科Id */
@property (nonatomic, assign) NSInteger subjectBaseId;
@end
複製代碼
可是因爲有業務需求,且爲了方便開發過程區分,須要對考試名稱的字段examSubjectName爲全科或者語數外的狀況,要特殊處理。因此,按照一向的思惟,咱們要重寫set方法框架
- (void)setExamSubjectName:(NSString *)examSubjectName{
_examSubjectName = examSubjectName;
if ([examSubjectName isEqualToString:@"全科"]) {
self.subjectBaseId = -100;
}
if ([examSubjectName isEqualToString:@"語數外"]) {
self.subjectBaseId = -200;
}
}
複製代碼
乍一看,也沒什麼問題,解析的過程當中,把字段的值轉化爲咱們須要的。並且真機實測的時候,全部的測試機都沒問題,除了一臺iPhone5以外 就除了一臺iPhone5,debug的時候看到set方法確實也走了,但是最終的subjectBaseId並無轉化成-100或者-200,可見subjectBaseId又被json自己的值覆蓋了,也就是說 set方法的執行順序,在不一樣CPU架構設備上存在差別。測試
那麼如何解決問題呢? 正是由於存在這樣的差別,因此咱們只能在model全部的字段所有set完畢以後,再作一些特殊的字段處理,那麼如何來處理呢? 翻閱YYModel源碼,確定能有所發現,果不其然,有所收穫。ui
/**
If the default json-to-model transform does not fit to your model object, implement
this method to do additional process. You can also use this method to validate the
model's properties. @discussion If the model implements this method, it will be called at the end of `+modelWithJSON:`, `+modelWithDictionary:`, `-modelSetWithJSON:` and `-modelSetWithDictionary:`. If this method returns NO, the transform process will ignore this model. @param dic The json/kv dictionary. @return Returns YES if the model is valid, or NO to ignore this model. */ - (BOOL)modelCustomTransformFromDictionary:(NSDictionary *)dic; 複製代碼
YYModel提供了這麼個方法,它會在+modelWithJSON:
, +modelWithDictionary:
, -modelSetWithJSON:
and -modelSetWithDictionary:
方法結束的時候調用。 因此咱們對model特殊字段的處理,都應該放到這個方法去執行this
- (BOOL)modelCustomTransformFromDictionary:(NSDictionary *)dic{
if ([self.examSubjectName isEqualToString:@"全科"]) {
self.subjectBaseId = -100;
}
if ([self.examSubjectName isEqualToString:@"語數外"]) {
self.subjectBaseId = -200;
}
return YES;
}
複製代碼
這麼一來,問題就解決了。 注意,YYModel還有一個- (NSDictionary *)modelCustomWillTransformFromDictionary:(NSDictionary *)dic;
這個方法很相似,可是執行的時機不同,這個方法是在model轉化以前執行,雖不符合本案例的需求,可是頗有可能在其餘相似的狀況能用的上。atom