美文网首页
简单的Model和Dictionary 互转

简单的Model和Dictionary 互转

作者: 有梦想的程序员 | 来源:发表于2019-08-10 13:59 被阅读0次

又一周了,新学习了点东西,整理一下。目前坚持每周发两篇文章,至少有一篇是有点东西的。
本周第一篇。

我们平常都使用第三方框架给我们提供好的DictionaryModel,比如:YYModel等,笔者长时间机械使用,却不太明白怎么实现的,花了点时间学习了一下,自己做了一个简单的实现。

1、DictionaryModel;

首先DictionaryModel,的思路:

  • 获取Dictionary的所有key
  • 根据Dictionary的key获取Value;
  • 给对象发消息

照常,有一个Book
//Book.h

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface Book : NSObject

@end

NS_ASSUME_NONNULL_END

//Book.m

#import "Book.h"

@implementation Book

@end
字典转模型
- (instancetype)initWithDictionary:(NSDictionary *)dic{
    self = [super init];
    if (self) {
        
        //获取字典的所有keys
        NSArray *allKeys = dic.allKeys;
        
        //遍历keys
        for (NSString *key in allKeys) {
            
            //根据key获取value
            id value = dic[key];
            
            //发消息
            NSString *methodName = [NSString stringWithFormat:@"set%@:",key.capitalizedString];
            
            //获取方法编号
            SEL sel = NSSelectorFromString(methodName);
            
            //发消息
            if (sel) {
                //返回类型 (函数名*)(param1,param2....)
                //((void (*)(id,SEL,NSString *))objc_msgSend)(self, sel, value);
                objc_msgSend(self, sel, value);
            }
        }
    }
    return self;
}

编译之后报错了,Too many arguments to function call, expected 0, have 3

image.png

查询objc_msgSend

头文件告诉我们 These functions must be cast to an appropriate function pointer type before being called.
意思是:调用之前我们需要转换为一个适当的函数指针类型。

image.png

菜鸡笔者只能使用翻译了~~ 囧。

那这里的函数指针怎么用呢?
  • 格式如下:
    函数返回值 (函数名 *) (param1 类型, param2 类型, param3 类型, ...)
    所以上述 void objc_msgSend(void /* id self, SEL op, ... */ ) 的类型为((void (*)(id, SEL, NSString *))objc_msgSend)(self, sel, value);
image.png

这里虽然有很多问题,逻辑什么都不严谨,但是知道了原理,就可以慢慢装修了。

2、ModelDictionary;

ModelDictionary,的思路:

  • 获取Model的属性名称的String(也就是字典的key);
  • Dictionary的 [dictionary setValue:value forKey:key];

代码如下,注释都有:

//模型转字典
- (NSDictionary *)dictionaryWithModel{
    
    /*
    Model转Dictionary的思路:
    1、获取Model的属性名称的String(也就是字典的key);
    2、Dictionary的 [dictionary setValue:value forKey:key];
    */
    
    NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init];
    
    //声明一个 int 类型的 outCount
    unsigned int outCount = 0;
    
    // typedef struct property_t *objc_property_t;
    // class_copyPropertyList 获取一个对象的所有属性, 返回值为 objc_property_t 的 List
    objc_property_t *propertyList = class_copyPropertyList([self class], &outCount);
    
    //如果有属性存在
    if (outCount > 0) {
        for (int i = 0; i < outCount; i++) {
            
            /*
             struct property_t {
             const char *name;
             const char *attributes;
             };
             */
            
            //获取数组中的每一个元素 objc_property_t
            objc_property_t property_t  = propertyList[i];
            
            //获取字符串类型的名字
            const char *propertyName = property_getName(property_t);
            NSString *name = [NSString stringWithUTF8String:propertyName];
            
            //方法编号
            SEL sel = NSSelectorFromString(name);
            
            //发消息取值
            id value = ((id (*)(id,SEL)) objc_msgSend)(self,sel);
            
            //赋值
            [dictionary setValue:value forKey:name];
        }
        
        //释放指针返回值
        free(propertyList);
        return dictionary;
    }
    
    //释放指针
    free(propertyList);
    return nil;
}

相关文章

网友评论

      本文标题:简单的Model和Dictionary 互转

      本文链接:https://www.haomeiwen.com/subject/fccrjctx.html