標籤:ios 歸檔 代碼 nscoding
MJExtension很強大,幾乎支援現有所有的模型、字典、json資料轉換,而且效率非常高
以前寫對象歸檔的時候,需要讓這個對象實現NSCoding協議,而且要對每一個需要歸檔的屬性做一些encode和decode操作,例如你之前的代碼可能是這樣子的
Person.h檔案
#import "Person.h"@interface Person : NSObject <NSCoding>@property (nonatomic,copy) NSString *name;@property (nonatomic,assign) int age;@property (nonatomic,assign) BOOL gay;@end
Person.m檔案
#import "Person.h"@implementation Person-(id)initWithCoder:(NSCoder *)aDecoder{ if (self = [super init]) { self.name = [aDecoder decodeObjectForKey:@"name"]; NSNumber *at = [aDecoder decodeObjectForKey:@"age"]; self.age = at.intValue ; NSNumber *isgay = [aDecoder decodeObjectForKey:@"gay"]; self.gay = isgay.intValue; } return self;}/** * 將對象寫入檔案的時候調用 * 怎樣儲存 * * @param aCoder aCoder */-(void)encodeWithCoder:(NSCoder *)aCoder{ [aCoder encodeObject:self.name forKey:@"name"]; [aCoder encodeObject:[NSNumber numberWithInt:self.age] forKey:@"age"]; [aCoder encodeObject:[NSNumber numberWithInt:self.gay] forKey:@"gay"];}@end
這需要重寫initWithCoder和encodeWithCoder這兩個方法,比較繁瑣,這和Android裡面的實現Parcelable差不多,要寫一大堆的代碼,不過Android有解決這個問題的方案,通過安裝AndroidStudio外掛程式來解決,請看前面講的AndroidStudio-Parcelable自動產生代碼外掛程式安裝和使用這篇文章,其實,IOS裡面也有相關的解決方案,而且比Android實現更簡單,快速和高效,一句代碼搞定,不信?之前我也不信,但是當我看到MJExtension之後,我就信了!
MJExtension非常好用但是容易被忽略的功能:不管你的模型屬性有幾百個,只需要加一句宏MJCodingImplementation,就能實現歸檔解檔,不用再編寫噁心的encodeWithCoder:和initWithCoder:了
程式碼範例如下,Person.h代碼不變,只需要將Person.m檔案內容改成下面的就OK了:
#import "Person.h"#import "MJExtension.h"@implementation PersonMJCodingImplementation@end
搞定,啥玩意,這樣寫就實現了?不是坑人的吧,肯定不是嘍,其實歸檔和反歸檔代碼本質上都要寫,只不過MJExtension幫我們做了,我們去點擊這個MJCodingImplementation去看看,發現代碼是這樣的:
#import <Foundation/Foundation.h>@interface NSObject (MJCoding)/** * 解碼(從檔案中解析對象) */- (void)decode:(NSCoder *)decoder;/** * 編碼(將對象寫入檔案中) */- (void)encode:(NSCoder *)encoder;@end/** 歸檔的實現 */#define MJCodingImplementation - (id)initWithCoder:(NSCoder *)decoder { if (self = [super init]) { [self decode:decoder]; } return self; } - (void)encodeWithCoder:(NSCoder *)encoder { [self encode:encoder]; }
再看實作類別代碼
#import "NSObject+MJCoding.h"#import "NSObject+MJMember.h"@implementation NSObject (MJCoding)/** * 編碼(將對象寫入檔案中) */- (void)encode:(NSCoder *)encoder{ [self enumerateIvarsWithBlock:^(MJIvar *ivar, BOOL *stop) { if (ivar.isSrcClassFromFoundation) return; [encoder encodeObject:ivar.value forKey:ivar.name]; }];}/** * 解碼(從檔案中解析對象) */- (void)decode:(NSCoder *)decoder{ [self enumerateIvarsWithBlock:^(MJIvar *ivar, BOOL *stop) { if (ivar.isSrcClassFromFoundation) return; ivar.value = [decoder decodeObjectForKey:ivar.name]; }];}@end
它其實就幫我們實現了把所有屬性都歸檔和反歸檔的操作,那麼問題來了,加入我不想所有的檔案都歸檔,我只想歸檔name和age屬性,不想歸檔gay屬性,那怎麼辦呢?其實MJExtension已經幫我們想好了,只需要調用一下:
[Person setupIgnoredCodingPropertyNames:^NSArray *{ return @[@"gay"];}];
這個方法就可以了!!!!!!!!
最後附上MJExtension的github地址
IOS-MJExtension一句話搞定對象歸檔