美文网首页
runtime 案例(一键拷贝model对象)

runtime 案例(一键拷贝model对象)

作者: 叩首问路梦码为生 | 来源:发表于2018-12-18 12:02 被阅读6次

    首先了解两个概念:深拷贝和浅拷贝
    简单来说,深拷贝就是内容拷贝,浅拷贝就是指针拷贝。更具体的用法,就不作过多解释,自行百度吧。

    // 字符串是直接赋值的,右侧如果是copy,那么就是浅拷贝;右侧如果是mutableCopy,那么就是深拷贝。  
       NSString *string1 = @"helloworld";  
       NSString *string2 = [string1 copy]; // 浅拷贝  
       NSString *string3 = [string1 mutableCopy]; // 深拷贝  
       NSMutableString *string4 = [string1 copy]; // 浅拷贝  
       NSMutableString *string5 = [string1 mutableCopy]; // 深拷贝  
    
       NSLog(@"string1 = %d;string2 = %d",string1,string2);  
       NSLog(@"string1 = %d;string3 = %d",string1,string3);  
       NSLog(@"string1 = %d;string4 = %d",string1,string4);  
       NSLog(@"string1 = %d;string5 = %d",string1,string5);  
    
    

    打印结果:

    [图片上传失败...(image-b9c25b-1545105761123)]


    使用场景:

    在某些时候,需要复制一份相同的Model数据,但是又不影响原Model,类似上述的深拷贝,又或者在大量相同字段中需要改变其中一个字段的值。由于Model数据的复杂性或者没有实现NSCopy协议,简单的使用Copy来拷贝可能无法达到预期效果,由此就有了MJExtension的衍生使用。

    核心代码:

    //
    //  NSObject+TMCopy.h
    //  LJDY
    //
    //  Created by TIM on 16/8/23.
    //  Copyright © 2016年 mimi. All rights reserved.
    //
    
    #import <Foundation/Foundation.h>
    
    @interface NSObject (TMCopy)
    
    /**
     实现类的copy
     */
    - (id)tm_copy;
    
    @end
    
    
    //
    //  NSObject+TMCopy.m
    //  LJDY
    //
    //  Created by TIM on 16/8/23.
    //  Copyright © 2016年 mimi. All rights reserved.
    //
    
    #import "NSObject+TMCopy.h"
    
    @implementation NSObject (TMCopy)
    
    - (id)tm_copy
    {
        Class clazz = [self class];;
        __strong Class newClass = [[clazz alloc] init];
        Class superClass = self.superclass;
        while (superClass && ![NSStringFromClass(superClass) isEqualToString:@"NSObject"]) {
            [self setupValueWithNewClass:newClass Class:superClass];
            superClass = superClass.superclass;
        }
        [self setupValueWithNewClass:newClass Class:clazz];
        return newClass;
    }
    
    - (void)setupValueWithNewClass:(Class)newClass
                             Class:(Class)clazz
    {
        int i;
        unsigned int propertyCount = 0;
        //runtime 获取类的所有属性
        objc_property_t *propertyList = class_copyPropertyList(clazz, &propertyCount);
        NSDictionary *dic;
        //获取数组中需要转换的模型类
        if ([clazz respondsToSelector:@selector(mj_objectClassInArray)]) {
            dic = [clazz mj_objectClassInArray];
        }
        for (i = 0; i < propertyCount; i++) {
            objc_property_t *thisProperty = propertyList + i;
            const char *propertyName = property_getName(*thisProperty);
            //属性名
            NSString *property = [NSString stringWithCString:propertyName encoding:NSUTF8StringEncoding];
            id value = [self valueForKey:property];
            //如果对象是模型类,则再次遍历模型类中的属性
            if (dic && [[dic allKeys] containsObject:property]) {
                //特殊处理模型中包含模型数组
                if ([value isKindOfClass:[NSArray class]]) {
                    NSMutableArray *modelArray = [NSMutableArray array];
                    for (Class _arrayClass in value) {
                        [modelArray addObject:[_arrayClass tm_copy]];
                    }
                    [newClass setValue:modelArray forKey:property];
                }
                else {
                    id _class = [value tm_copy];
                    [newClass setValue:_class forKey:property];
                }
            }
            else {
                [newClass setValue:value forKey:property];
            }
        }
        free(propertyList);
    }
    
    @end
    
    

    使用方法:

    FriendItem *_item = [item tm_copy];
    
    

    结果:

    [图片上传失败...(image-d06720-1545105761123)]

    作者:提呐个莫
    链接:https://www.jianshu.com/p/c4fd7dd4697e
    來源:简书
    简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

    相关文章

      网友评论

          本文标题:runtime 案例(一键拷贝model对象)

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