天天看點

IOS-MJExtension一句話搞定對象歸檔MJExtension很強大,幾乎支援現有所有的模型、字典、json資料轉換,而且效率非常高

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位址