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