runtimeを使用してモデルオブジェクトをアーカイブする
4194 ワード
開発では常にいくつかのオブジェクトを保存する必要があります.もちろんこれは軽量級です.まずNSUserDefaultsを使用して保存することを考えますが、NSUserDefaultsが直接保存できるオブジェクトのタイプも限られています.例えば、NSArray、NSData、NSDictionary、NSNumber、NSString、私たちが構築したモデルオブジェクトに対して、NSUserDefaultsが直接保存すると、少し力が入らなくなって、この时、私达はよく模型のオブジェクトに対してアーカイブを行って、アーカイブは简単ですが、しかし、いくつか考えてみて、もしあなたの模型のメンバーが比较的に多いならば、手动で実现するのはとても时间がかかって、新しいNSObjectの分类を创建することができて、runtime遍歴性を使ってアーカイブを実现します
. hファイル
. mファイル
モデルオブジェクトのimplementationでマクロを直接呼び出す
. hファイル
//
// DVVCoding.h
// DVVCoding
//
// Created by on 2016/11/21.
// Copyright © 2016 devdawei. All rights reserved.
//
#import
@protocol DVVCodingDelegate
@optional
/**
,
*/
+ (NSArray *)dvv_codingIgnoreProperties;
@end
@interface NSObject (DVVCoding)
/**
* ( )
*/
- (void)dvv_decode:(NSCoder *)decoder;
/**
* ( )
*/
- (void)dvv_encode:(NSCoder *)encoder;
/**
*
*/
#define DVVCodingImplementation \
- (instancetype)initWithCoder:(NSCoder *)aDecoder \
{ \
self = [super init]; \
if (self) { \
[self dvv_decode:aDecoder]; \
} \
return self; \
} \
\
- (void)encodeWithCoder:(NSCoder *)coder \
{ \
[self dvv_encode:coder]; \
}
@end
. mファイル
//
// DVVCoding.m
// DVVCoding
//
// Created by on 2016/11/21.
// Copyright © 2016 devdawei. All rights reserved.
//
#import "DVVCoding.h"
#import
typedef NS_ENUM(NSUInteger, DVVCodingType)
{
DVVCodingTypeEncode,
DVVCodingTypeDecode,
};
@implementation NSObject (DVVCoding)
- (void)dvv_encode:(NSCoder *)encoder
{
[self dvv_codingFor:encoder type:DVVCodingTypeEncode];
}
- (void)dvv_decode:(NSCoder *)decoder
{
[self dvv_codingFor:decoder type:DVVCodingTypeDecode];
}
- (void)dvv_codingFor:(NSCoder *)coder type:(DVVCodingType)type
{
NSArray *ignoreProperties = nil;
if ([[self class] respondsToSelector:@selector(dvv_codingIgnoreProperties)])
{
ignoreProperties = (NSArray *)[[self class] performSelector:@selector(dvv_codingIgnoreProperties)];
}
if (!ignoreProperties) ignoreProperties = [NSArray array];
//
NSMutableArray *defaultIgnoreProperties = [NSMutableArray arrayWithObjects:@"hash", @"superclass", @"description", @"debugDescription", nil];
ignoreProperties = [defaultIgnoreProperties arrayByAddingObjectsFromArray:ignoreProperties];
unsigned int count;
//
objc_property_t *properties = class_copyPropertyList(self.class, &count);
for (unsigned int i = 0; i < count; i++)
{
//
objc_property_t property = properties[i];
//
const char *name = property_getName(property);
NSString *propertyName = [NSString stringWithUTF8String:name];
//
if (ignoreProperties)
{
BOOL flage = NO;
for (NSString *ignorePropertyName in ignoreProperties)
{
if ([propertyName isEqualToString:ignorePropertyName])
{
flage = YES;
break;
}
}
if (flage)
{
continue;
}
}
//
NSString *propertyValue = nil;
//
if (DVVCodingTypeEncode == type)
{
propertyValue = [self valueForKey:propertyName];
if(propertyValue) [coder encodeObject:propertyValue forKey:propertyName];
}
//
else if (DVVCodingTypeDecode == type)
{
propertyValue = [coder decodeObjectForKey:propertyName];
if(propertyValue) [self setValue:propertyValue forKey:propertyName];
}
}
//
free(properties);
}
@end
モデルオブジェクトのimplementationでマクロを直接呼び出す
#import "MMRDMUserInfo.h"
@implementation MMRDMUserInfo
// , ,
DVVCodingImplementation
/**
,
@return
*/
+ (NSArray *)dvv_codingIgnoreProperties
{
return @[ @"property_1", @"property_2" ];
}
@end