• 【面试题】为什么字符串用copy修饰


    1.

    假如有一个NSMutableString,现在用他给一个retain修饰 NSString赋值,那么只是将NSString指向了NSMutableString所指向的位置,并对NSMUtbaleString计数器加一,此时,如果对NSMutableString进行修改,也会导致NSString的值修改,原则上这是不允许的. 如果是copy修饰的NSString对象,在用NSMutableString给他赋值时,会进行深拷贝,及把内容也给拷贝了一份,两者指向不同的位置,即使改变了NSMutableString的值,NSString的值也不会改变.

    所以用copy是为了安全,防止NSMutableString赋值给NSString时,前者修改引起后者值变化而用的.

     2

    我这样说你就明白了 A->B A中的一个MutableString给B中的一个Property(NSString类型)赋值 首先是能接受的,父类可以接受子类,如果是retain,仅仅是生成一个指针,计数器加一,然后指向那个MutableString。如果MString改变,B中那个跟着改变,因为是同一块内存区域。而选择Copy相当于又生成了一个NSString,与A中的MutableString独立。 

     3.

    下面我想通过一个最简单的例子来说明它们的区别:

    首先我们来看看使用strong会出现什么样的情况:

    .h

    @property (nonatomic, strong) NSString *name;

    .m

    NSMutableString *mStr = [NSMutableString stringWithString:@"张三"];

    self.name = mStr;

    NSLog(@"使用strong第一次得到的名字:%@", self.name);

    [mStr appendString:@"丰"];

    NSLog(@"使用strong第二次得到的名字:%@", self.name);

    打印结果:

    2017-04-07 16:20:10.138793 copyTest[2421:682898]使用strong第一次得到的名字:张三

    2017-04-07 16:20:10.138884 copyTest[2421:682898]使用strong第二次得到的名字:张三丰

    结论:

    通过上面的例子我们可以看出,我们在没有直接修改 self.name 的情况下 self.name 却被修改了,就好像一个人的名字怎么能没有经过自己同意就被修改呢?我们的初衷只是想修改mStr,但是 self.name 却被意外的修改了,而这就是我们使用strong所不想看到的,它会破坏程序的封装性。(使用strong后 self.name 和 mStr 指向的是同一片内存,所以修改其中一个值后两个值就都变了)

    那么使用copy又会得到什么结果呢?下面是使用copy的例子:

    .h

    @property (nonatomic, copy) NSString *name;

    .m

    NSMutableString *mStr = [NSMutableString stringWithString:@"张三"];

    self.name = mStr;

    NSLog(@"使用copy第一次得到的名字:%@", self.name);

    [mStr appendString:@"丰"];

    NSLog(@"使用copy第二次得到的名字:%@", self.name);

    打印结果:

    2017-04-07 16:35:04.012589 copyTest[2428:685221]使用copy第一次得到的名字:张三

    2017-04-07 16:35:04.012676 copyTest[2428:685221]使用copy第二次得到的名字:张三

    结论:

    这个例子中我们使用了copy修饰,mStr通过copy得到了一个新的对象赋值给 self.name 这样我们再修改mStr就跟 self.name 没关系了,只有直接对 self.name 进行赋值才能改变它的值,这样就保证了程序的封装性。

    为什么使用copy而不是strong以上只是一个例子,还有很多情况可以自己去试试,并且可以把属性类型改成NSMutableString进行不同情况的研究,也可以更加深入理解深拷贝和浅拷贝的含义。

     4.

    copy会重新生成一个string,被copy的对象发生改变时,copy后的对象不改变
    strong仅仅进行强引用确保持有string的对象在生存期间这个string不会被释放

    题主说的问题有点问题,应该是NSString用copy或strong都可以,下面分场景说:

    • 必须使用copy的场景:A对象持有string记做A.string,然后赋值给B对象,记做B.string,若希望B.string的内容改变时A.string不改变就必须用copy
    • 必须用strong的场景:若希望B.string的内容改变时同时A.string也改变则必须用strong
    • 随便用哪个的场景:string的内容不会被改变的情况下

    以上规则不止适用于NSString,NSArray,NSDictionary等同理.

  • 相关阅读:
    第十周课程总结
    第九周课程总结&实验报告(七)
    第八周课程总结&实验报告(六)
    第七周课程总结&实验报告(五)
    第六周&java实验报告四
    第五周课程总结&试验报告(三)
    课程总结
    第十四周课程总结
    第十三周学习总结
    第十二周编程总结
  • 原文地址:https://www.cnblogs.com/wangbinios/p/7724892.html
Copyright © 2020-2023  润新知