首先了解兩個概念:深拷貝和淺拷貝。
簡單來講,深拷貝就是內容拷貝,淺拷貝就是指針拷貝。更具體的用法,就不做過多解釋,自行百度吧。數組
// 字符串是直接賦值的,右側若是是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);
打印結果:this
在某些時候,須要複製一份相同的Model數據,可是又不影響原Model,相似上述的深拷貝,又或者在大量相同字段中須要改變其中一個字段的值。因爲Model數據的複雜性或者沒有實現NSCopy協議,簡單的使用Copy來拷貝可能沒法達到預期效果,由此就有了MJExtension的衍生使用。spa
// // 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];