Realm是由美国YCombinator
孵化的创业团队历时几年打造,第一个专门针对移动平台设计的数据库。Objective‑C
版本的Realm
能够让您以一种安全、耐用以及迅捷的方式来高效地编写应用的数据模型层。
最近使用过程中遇到问题,就是RLMObject
的解析与Copy
,正常处理无法完成。
问题
其实两个问题最终归为一个问题就是使用Realm
项目中继承RLMObject
的对象,在获取类名发现我们无法获取到对应的类名。
解决办法
#import <Foundation/Foundation.h>
#import "MJExtension.h"
#import <Realm.h>
NS_ASSUME_NONNULL_BEGIN
@interface SRDishTypeModel : RLMObject
@property (nonatomic, copy) NSString * name;
@property (nonatomic, assign) NSInteger id;
@end
NS_ASSUME_NONNULL_END
正常情况下我们获取对象的类名,一般是这样的[object class]
SRDishTypeModel *model = [[SRDishTypeModel alloc]init];
model.name = @"张三";
model.id = 5;
NSLog(@"%@",[model class]);
结果1
这样就导致我们无法取到类名,那么就无法完成后续操作了。
RLMObject
提供了一个方法给我们去获取这个对象的类名;
+ (NSString *)className;
接下来我们重新
SRDishTypeModel *model = [[SRDishTypeModel alloc]init];
model.name = @"张三";
model.id = 5;
NSLog(@"%@",[model class]);
NSLog(@"%@",[[model class] className]);
结果2
这样问题就解决了。
-(id)copyWithZone:(NSZone *)zone{
SRDishTypeModel *model = [[[self class] allocWithZone:zone] init];
unsigned int count = 0;
objc_property_t *properties = class_copyPropertyList([self class], &count);
for (int i = 0; i < count; i++) {
objc_property_t property = properties[i];
const char *name = property_getName(property);
NSString *propertyName = [NSString stringWithUTF8String:name];
id value = [self valueForKey:propertyName];
if (value) {
[model setValue:value forKey:propertyName];
}
}
free(properties);
return model;
}
上面方法实现model
的copy
,但是你会发现copy下来的都为空。
-(id)copyWithZone:(NSZone *)zone{
SRDishTypeModel *model = [[[NSClassFromString([[self class] className]) class] allocWithZone:zone] init];
unsigned int count = 0;
objc_property_t *properties = class_copyPropertyList(NSClassFromString([[self class] className]), &count);
for (int i = 0; i < count; i++) {
objc_property_t property = properties[i];
const char *name = property_getName(property);
NSString *propertyName = [NSString stringWithUTF8String:name];
id value = [self valueForKey:propertyName];
if (value) {
[model setValue:value forKey:propertyName];
}
}
free(properties);
return model;
}
到这里问题就解决了。
最后附上通过runtime
解析。
#import "RLMObject+Json.h"
#import <objc/runtime.h>
@implementation RLMObject (Json)
#pragma mark -模型转字典
-(NSMutableDictionary*)rl_keyValues{
NSMutableDictionary *propertyDic = [NSMutableDictionary dictionaryWithCapacity:0];
unsigned int outCount;
//获取对象的属性列表
objc_property_t *properties = class_copyPropertyList(NSClassFromString([[self class] className]), &outCount);
for (int i = 0; i < outCount; i++) {
NSString *name = [NSString stringWithCString:property_getName(properties[i]) encoding:NSUTF8StringEncoding];
id value = [self valueForKey:name];
if (value) {
if ([value isKindOfClass:[RLMArray class]]) {//判断是否是数组
//模型数组转字典数组成
[propertyDic setObject:[self rl_keyValuesArrayWithObjectArray:value] forKey:name];
}else{
[propertyDic setObject:value forKey:name];
}
}
}
free(properties);
return propertyDic;
}
#pragma mark - 模型数组 -> 字典数组
-(NSMutableArray*)rl_keyValuesArrayWithObjectArray:(NSArray *)objectArray{
NSMutableArray *array = [[NSMutableArray alloc]init];
for (RLMObject *obje in objectArray) {
[array addObject:obje.rl_keyValues];
}
return array;
}