NSstring为什么使用copy copy的深度解析

面试中经常问到的一个题,如果只是答到copy就是会单独复制一份,重新开辟一个地址空间。不会因为原值的修改而修改。这样回答100分只是拿到了10分。面试官会进一步追问。直到问到你不会。。。

入门的回答以后,递进问题。

1.那你跟我说一下copy 还有strong的区别

上代码

@property (nonatomic, strong) NSString *strongString;
@property (nonatomic, copy) NSString *copyedString;
    NSMutableString *string = [NSMutableString stringWithFormat:@"aaa"];
    self.strongString = string;
    self.copyedString = string;
    //string = [NSMutableString stringWithFormat:@"aaa"];
    NSLog(@"origin string: %p, %p", string, &string);
    NSLog(@"strong string: %p, %p", _strongString, &_strongString);
    NSLog(@"copy string: %p, %p", _copyedString, &_copyedString);
    self.outputLabel.text = [NSString stringWithFormat:@"origin string:%@\n,strong string:%@\n,copy string %@",string,_strongString,_copyedString];
    [string appendString:@"bbb"];
    NSLog(@"origin string: %p, %p", string, &string);
    NSLog(@"strong string: %p, %p", _strongString, &_strongString);
    NSLog(@"copy string: %p, %p", _copyedString, &_copyedString);
    self.outputLabel.text = [NSString stringWithFormat:@"origin string:%@\n,strong string:%@\n,copy string %@",string,_strongString,_copyedString];

看一下输出结果:



可以看到,strong string的指向内存地址和string是一样的。但是copy string是不一样的,也就是说copy但开辟了内存地址。从输出结果看,copy string并没有因为string的内容修改而改变。但是strong就被改变了。因为strong是指针拷贝(引用计数拷贝)。而copy是内容拷贝(深拷贝)

2.那什么情况下copy 和 strong修饰,效果是一样的。

上代码:

    NSString *string = [NSString stringWithFormat:@"aaa"];
    self.strongString = string;
    self.copyedString = string;
    //string = [NSMutableString stringWithFormat:@"aaa"];
    NSLog(@"origin string: %p, %p", string, &string);
    NSLog(@"strong string: %p, %p", _strongString, &_strongString);
    NSLog(@"copy string: %p, %p", _copyedString, &_copyedString);
    self.outputLabel.text = [NSString stringWithFormat:@"origin string:%@\n,strong string:%@\n,copy string %@",string,_strongString,_copyedString];

                         

可以看到 如果是不可变拷贝不可变的副本,是不会重新开辟空间。输出就可以看到。3块输出的内存地址是一样的。这同样适用于数组。

3.那如果是自定义类,你怎么让它具有copy功能。能大概跟我说一下ios是如何处理的

答:遵守NScoping协议,实现copywithzone方法。大致流程如下图


4.block为什么使用copy

block使用copy是在MRC中延续下来的,在MRC下,方法内部的block是存放在栈区,使用copy会将block拷贝到堆区。
在ARC下编译器会自动对block进行copy,因此我们使用copy或者strong的效果是一样的。但是我们在ARC下继续使用copy可以提醒我们编译器会自动帮我们实现copy的操作。

typedef void (^AlertBlock)();
@interface AwardView : UIView
@property (nonatomic,copy) AlertBlock closeBlock;
@end


猜你喜欢

转载自blog.csdn.net/lee727n/article/details/80110300
今日推荐