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

上一篇下一篇

猜你喜欢

热点阅读