jscjxysx 2019-06-28
首先了解两个概念:深拷贝和浅拷贝。
简单来说,深拷贝就是内容拷贝,浅拷贝就是指针拷贝。更具体的用法,就不作过多解释,自行百度吧。
// 字符串是直接赋值的,右侧如果是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];