美文网首页iOS学习程序员iOS Developer
iOS开发之:copy和mutableCopy

iOS开发之:copy和mutableCopy

作者: life白玉兰 | 来源:发表于2017-03-28 23:57 被阅读106次

    前几天面试被问到copy和mutableCopy的知识,一开始答得是对的,但是被面试官饶了几圈就有点懵了,因为对方问的问题虽然表述不一样,但是后面问的问题在我感觉已经和前面的重复了两三次了,所以回答的时候有些犹豫,有些怀疑是不是自己没听明白对方的意思,然后就没跟上对方的节奏懵了😂

    大篇幅的理论我没有时间去写,所以就简单写了点代码来测试下copy和mutableCopy的各种情况,如果有不对的或者不全的地方请大神指正!🙏

    为了简单我只以NSArray和NSMutableArray为例来说明

    第一种:copy方法,NSArray赋值

    NSArray *array = [[NSArray alloc]init];

    NSMutableArray *mutableArray = [[NSMutableArray alloc]init];

    NSArray *baseArray = [NSArray arrayWithObjects:@"aaaaa", @"bbbb", @"ccccc", @"Block", nil];

    array = [baseArray copy];

    mutableArray = [baseArray copy];

    NSLog(@"origin array: %p, %p, %@",baseArray, &baseArray, baseArray);

    NSLog(@"copy array: %p, %p, %@",array, &array, array);

    NSLog(@"copy mutableArray: %p, %p, %@", mutableArray, &mutableArray, mutableArray);

    [mutableArray removeObjectAtIndex:0];

    运行时我打了断点然后po了一下baseArray、array和mutableArray的class,如下是打印出的结果:

    (lldb) po baseArray.class

    __NSArrayI

    (lldb) po array.class

    __NSArrayI

    (lldb) po mutableArray.class

    __NSArrayI

    可以看到,三者class类型都是__NSArrayI,mutableArray可变数组在经过copy方法后变成了不可变数组

     origin array: 0x600000057df0, 0x7fff51719bd0, (

    aaaaa,

    bbbb,

    ccccc,

    Block

    )

     copy array: 0x600000057df0, 0x7fff51719be0, (

    aaaaa,

    bbbb,

    ccccc,

    Block

    )

     copy mutableArray: 0x600000057df0, 0x7fff51719bd8, (

    aaaaa,

    bbbb,

    ccccc,

    Block

    )

    可以看到,三者指向的地址是一样的

    -[__NSArrayI removeObjectAtIndex:]: unrecognized selector sent to instance 0x60000005de20

    也证明了mutableArray确实变成了不可变数组

    *小结:用copy方法时,如果被copy对象为不可变类型,此时为浅拷贝,被赋值对象无论是否可变都将变为不可变对象

    第二种:copy方法,NSMutableArray赋值

    在.m文件中将

    NSArray *baseArray = [NSArray arrayWithObjects:@"aaaaa", @"bbbb", @"ccccc", @"Block", nil];

    改为:

    NSMutableArray *baseArray = [NSMutableArray arrayWithObjects:@"aaaaa", @"bbbb", @"ccccc", @"Block", nil];

    其他保持不变,我们继续运行,同样po一下:

    (lldb) po baseArray.class

    __NSArrayM

    (lldb) po array.class

    __NSArrayI

    (lldb) po mutableArray.class

    __NSArrayI

    在这里可以看出,baseArray没有变(当然不会变🙄)依然是可变数组,array和mutableArray则是不可变数组

     origin array: 0x608000047c80, 0x7fff52b7ebd8, (

    aaaaa,

    bbbb,

    ccccc,

    Block

    )

    copy array: 0x600000055f60, 0x7f80c141fe68, (

    aaaaa,

    bbbb,

    ccccc,

    Block

    )

    copy mutableArray: 0x60800004d6e0, 0x7f80c141fe70, (

    aaaaa,

    bbbb,

    ccccc,

    Block

    )

    这里可以看出array和mutableArray在copy方法时生成了新的对象

     -[__NSArrayI removeObjectAtIndex:]: unrecognized selector sent to instance 0x60800004d6e0

    最后mutableArray执行删除操作发生奔溃

    *小结:用copy方法时,如果被copy对象为可变类型,此时为深拷贝,被赋值对象无论是否可变都将变为不可变对象

    第三种:mutableCopy方法,NSArray赋值

    NSArray *array = [[NSArray alloc]init];

    NSMutableArray *mutableArray = [[NSMutableArray alloc]init];

    NSArray *baseArray = [NSArray arrayWithObjects:@"aaaaa", @"bbbb", @"ccccc", @"Block", nil];

    array = [baseArray mutableCopy];

    mutableArray = [baseArray mutableCopy];

    NSLog(@"origin array: %p, %p, %@",baseArray, &baseArray, baseArray);

    NSLog(@"copy array: %p, %p, %@",array, &array, array);

    NSLog(@"copy mutableArray: %p, %p, %@", mutableArray, &mutableArray, mutableArray);

    [mutableArray removeObjectAtIndex:0];

    我们继续运行,同样po一下:

    (lldb) po baseArray.class

    __NSArrayI

    (lldb) po array.class

    __NSArrayM

    (lldb) po mutableArray.class

    __NSArrayM

    可以看到,array和mutableArray的class类型都是__NSArrayM,array不变数组在经过mutableCopy方法后变成了可变数组

     origin array: 0x608000059cb0, 0x7fff5b530bd0, (

    aaaaa,

    bbbb,

    ccccc,

    Block

    )

     copy array: 0x60000005e090, 0x7fff5b530be0, (

    aaaaa,

    bbbb,

    ccccc,

    Block

    )

    copy mutableArray: 0x6000000576a0, 0x7fff5b530bd8, (

    aaaaa,

    bbbb,

    ccccc,

    Block

    )

    这里可以看出array和mutableArray在mutableCopy方法时生成了新的对象,[mutableArray removeObjectAtIndex:0];不会再引起奔溃。

    *小结:用mutableCopy方法时,如果被mutableCopy对象为不可变类型,此时也为深拷贝,被赋值对象无论是否可变都将变为可变对象

    第四种:mutableCopy方法,NSMutableArray赋值

    NSArray *array = [[NSArray alloc]init];

    NSMutableArray *mutableArray = [[NSMutableArray alloc]init];

    NSMutableArray *baseArray = [NSMutableArray arrayWithObjects:@"aaaaa", @"bbbb", @"ccccc", @"Block", nil];

    array = [baseArray mutableCopy];

    mutableArray = [baseArray mutableCopy];

    NSLog(@"origin array: %p, %p, %@",baseArray, &baseArray, baseArray);

    NSLog(@"copy array: %p, %p, %@",array, &array, array);

    NSLog(@"copy mutableArray: %p, %p, %@", mutableArray, &mutableArray, mutableArray);

    [mutableArray removeObjectAtIndex:0];

    我们继续运行,同样po一下:

    (lldb) po baseArray.class

    __NSArrayM

    (lldb) po array.class

    __NSArrayM

    (lldb) po mutableArray.class

    __NSArrayM

    可以看到,三者class类型都是__NSArrayM,array不变数组在经过mutableCopy方法后变成了可变数组

    origin array: 0x600000051490, 0x7fff54acdbd0, (

    aaaaa,

    bbbb,

    ccccc,

    Block

    )

    copy array: 0x600000056c80, 0x7fff54acdbe0, (

    aaaaa,

    bbbb,

    ccccc,

    Block

    )

    copy mutableArray: 0x60800005bf00, 0x7fff54acdbd8, (

    aaaaa,

    bbbb,

    ccccc,

    Block

    )

    这里可以看出array和mutableArray在mutableCopy方法时生成了新的对象,[mutableArray removeObjectAtIndex:0];不会再引起奔溃。

    *小结:用mutableCopy方法时,如果被mutableCopy对象为可变类型,此时也为深拷贝,被赋值对象无论是否可变都将变为可变对象

    总结:

    1.copy在被拷贝对象为不可变类型时为浅拷贝,在被拷贝对象为可变类型时为深拷贝;

    2.无论copy的被拷贝对象是否可变,其返回值一定为不可变类型;

    3.mutableCopy为深拷贝,无论被拷贝对象是否可变,其返回值一定为可变类型;

    相关文章

      网友评论

        本文标题:iOS开发之:copy和mutableCopy

        本文链接:https://www.haomeiwen.com/subject/ogtsottx.html