iOS深拷贝(MutableCopy)与浅拷贝(Copy)的区别
2022-02-25 本文已影响0人
money_ac9e
一.将model传到新的controller
1.model需要继承<NSCopying,NSMutableCopying>
2.需要重写方法
- (id)copyWithZone:(NSZone *)zone
{
PersonModel *model = [[self class] allocWithZone:zone];
model.name = _name;
return model;
}
- (id)mutableCopyWithZone:(NSZone *)zone
{
PersonModel *model = [[self class] allocWithZone:zone];
model.name = _name;
return model;
}
这里必须重新将name字段重新赋值 有新的方法请告送我 谢谢🙏
补充:2022.4.2
使用两个宏可以满足需求
WZLSERIALIZE_CODER_DECODER();
WZLSERIALIZE_COPY_WITH_ZONE();
直接将这两个宏 放到.m中
#define WZLSERIALIZE_CODER_DECODER() \
\
- (id)initWithCoder:(NSCoder *)coder \
{ \
NSLog(@"%s",__func__); \
Class cls = [self class]; \
while (cls != [NSObject class]) { \
/*判断是自身类还是父类*/ \
BOOL bIsSelfClass = (cls == [self class]); \
unsigned int iVarCount = 0; \
unsigned int propVarCount = 0; \
unsigned int sharedVarCount = 0; \
Ivar *ivarList = bIsSelfClass ? class_copyIvarList([cls class], &iVarCount) : NULL;/*变量列表,含属性以及私有变量*/ \
objc_property_t *propList = bIsSelfClass ? NULL : class_copyPropertyList(cls, &propVarCount);/*属性列表*/ \
sharedVarCount = bIsSelfClass ? iVarCount : propVarCount; \
\
for (int i = 0; i < sharedVarCount; i++) { \
const char *varName = bIsSelfClass ? ivar_getName(*(ivarList + i)) : property_getName(*(propList + i)); \
NSString *key = [NSString stringWithUTF8String:varName]; \
id varValue = [coder decodeObjectForKey:key]; \
NSArray *filters = @[@"superclass", @"description", @"debugDescription", @"hash"]; \
if (varValue && [filters containsObject:key] == NO) { \
[self setValue:varValue forKey:key]; \
} \
} \
free(ivarList); \
free(propList); \
cls = class_getSuperclass(cls); \
} \
return self; \
} \
\
- (void)encodeWithCoder:(NSCoder *)coder \
{ \
NSLog(@"%s",__func__); \
Class cls = [self class]; \
while (cls != [NSObject class]) { \
/*判断是自身类还是父类*/ \
BOOL bIsSelfClass = (cls == [self class]); \
unsigned int iVarCount = 0; \
unsigned int propVarCount = 0; \
unsigned int sharedVarCount = 0; \
Ivar *ivarList = bIsSelfClass ? class_copyIvarList([cls class], &iVarCount) : NULL;/*变量列表,含属性以及私有变量*/ \
objc_property_t *propList = bIsSelfClass ? NULL : class_copyPropertyList(cls, &propVarCount);/*属性列表*/ \
sharedVarCount = bIsSelfClass ? iVarCount : propVarCount; \
\
for (int i = 0; i < sharedVarCount; i++) { \
const char *varName = bIsSelfClass ? ivar_getName(*(ivarList + i)) : property_getName(*(propList + i)); \
NSString *key = [NSString stringWithUTF8String:varName]; \
/*valueForKey只能获取本类所有变量以及所有层级父类的属性,不包含任何父类的私有变量(会崩溃)*/ \
id varValue = [self valueForKey:key]; \
NSArray *filters = @[@"superclass", @"description", @"debugDescription", @"hash"]; \
if (varValue && [filters containsObject:key] == NO) { \
[coder encodeObject:varValue forKey:key]; \
} \
} \
free(ivarList); \
free(propList); \
cls = class_getSuperclass(cls); \
} \
}
#define WZLSERIALIZE_COPY_WITH_ZONE() \
\
/*如果不实现copyWithZone:方法,则[personObject copy]时会崩溃*/ \
- (id)copyWithZone:(NSZone *)zone \
{ \
NSLog(@"%s",__func__); \
id copy = [[[self class] allocWithZone:zone] init]; \
Class cls = [self class]; \
while (cls != [NSObject class]) { \
/*判断是自身类还是父类*/ \
BOOL bIsSelfClass = (cls == [self class]); \
unsigned int iVarCount = 0; \
unsigned int propVarCount = 0; \
unsigned int sharedVarCount = 0; \
Ivar *ivarList = bIsSelfClass ? class_copyIvarList([cls class], &iVarCount) : NULL;/*变量列表,含属性以及私有变量*/ \
objc_property_t *propList = bIsSelfClass ? NULL : class_copyPropertyList(cls, &propVarCount);/*属性列表*/ \
sharedVarCount = bIsSelfClass ? iVarCount : propVarCount; \
\
for (int i = 0; i < sharedVarCount; i++) { \
const char *varName = bIsSelfClass ? ivar_getName(*(ivarList + i)) : property_getName(*(propList + i)); \
NSString *key = [NSString stringWithUTF8String:varName]; \
/*valueForKey只能获取本类所有变量以及所有层级父类的属性,不包含任何父类的私有变量(会崩溃)*/ \
id varValue = [self valueForKey:key]; \
NSArray *filters = @[@"superclass", @"description", @"debugDescription", @"hash"]; \
if (varValue && [filters containsObject:key] == NO) { \
[copy setValue:varValue forKey:key]; \
} \
} \
free(ivarList); \
free(propList); \
cls = class_getSuperclass(cls); \
} \
return copy; \
}
3.直接使用
{
PersonModel *model1 = [[PersonModel alloc] init];
model1.name = @"测试1";
PersonModel *copy1 = [model1 copy];
PersonModel *mucopy1 = [model1 mutableCopy];
NSLog(@"model1 is %@",model1);
NSLog(@"copy1 is %@",copy1);
NSLog(@"mucopy1 is %@",mucopy1);
NSLog(@"model1.name is %@",model1.name);
NSLog(@"copy1.name is %@",copy1.name);
NSLog(@"mucopy1.name is %@",mucopy1.name);
copy1.name = @"测试2";
mucopy1.name = @"测试3";
NSLog(@"model1.name is %@",model1.name);
NSLog(@"copy1.name is %@",copy1.name);
NSLog(@"mucopy1.name is %@",mucopy1.name);
}
二.将数组传到新的controller
数组中的model需要上面那么处理
创建数组时需要使用这个方法
- (instancetype)initWithArray:(NSArray<ObjectType> *)array copyItems:(BOOL)flag;
上代码 一看就明白
{
PersonModel *model1 = [[PersonModel alloc] init];
model1.name = @"测试1";
NSMutableArray *arr = [NSMutableArray arrayWithObject:model1];
NSMutableArray *arr1 = [arr copy];
NSMutableArray *arr2 = [arr mutableCopy];
NSLog(@"arr is %@",arr);
NSLog(@"arr1 is %@",arr1);
NSLog(@"arr2 is %@",arr2);
NSLog(@"arr is %p",arr);
NSLog(@"arr1 is %p",arr1);
NSLog(@"arr2 is %p",arr2);
NSMutableArray *arr3 = [[NSMutableArray alloc] initWithArray:arr copyItems:YES];
NSMutableArray *arr4 = [arr3 copy];
NSMutableArray *arr5 = [arr3 mutableCopy];
NSLog(@"arr3 is %@",arr3);
NSLog(@"arr4 is %@",arr4);
NSLog(@"arr5 is %@",arr5);
NSLog(@"arr3 is %p",arr3);
NSLog(@"arr4 is %p",arr4);
NSLog(@"arr5 is %p",arr5);
}
iOS深拷贝(MutableCopy)与浅拷贝(Copy)的区别
https://www.jianshu.com/p/5df570135ad2
iOS关于Copy和mutableCopy方法的浅析
https://blog.csdn.net/u013505811/article/details/106665194/
iOS中几个常用协议(一)NSCopying/NSMutableCopying)
https://www.jianshu.com/p/e98e6e30ebda