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 Person
MJCodingImplementation
@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位址