iOS开发系列--基于MJExtension的Runtime简单使用

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

// 字符串是直接赋值的,右侧如果是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);  

打印结果:



使用场景:

在某些时候,需要复制一份相同的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];

结果:

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 1.ios高性能编程 (1).内层 最小的内层平均值和峰值(2).耗电量 高效的算法和数据结构(3).初始化时...
    欧辰_OSR阅读 30,173评论 8 265
  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,619评论 1 32
  • 1雨夜凤凰 “咕噜咕噜……”行李箱的轮子同粗糙的石板路摩擦着,发出一声声沉闷而又仓促的响声。街边悬挂的酒旗早已被雨...
    四月负像阅读 268评论 1 0
  • 格外私塾公开课预告! 今晚九点我们将从《三字经》中继续聆听古人的智慧!“养不教,父之过,教不严,师之惰。” 这十...
    一蝉一树阅读 368评论 0 1
  • “最近怎么样?挺好的吧……” “嗯,挺好的,你呢?” “我啊,哎,每天都特别郁闷,特别焦虑,不知道……” …… 许...
    住在楼上的召唤喵阅读 1,109评论 3 0

友情链接更多精彩内容