一、@property的参数copy

1.例如,我这儿有1个Person

Person里面是不是有1个name属性啊,

我现在怎么写,我还是先这么写啊

在Person.h文件

#import <Foundation/Foundation.h>

@interface Person:NSObject

{

NSString *_name;

}

– (void)setName:(NSString *)name;

– (NSString *)name;

@end

在Person.m文件

#import “Person.h

@implementation Person

– (void)setName:(NSString *)name{

//我把ARC开起来啊,这时候应该怎么写,下划线的name等于name啊

_name = name;

}

– (NSString *)name{

return _name;

}

@end

大家思考一个问题,我创建1个Person对象,在main.m文件

#import <Foundation/Foundation.h>

#import “Person.h

int main(){

Person *p1 = [Person new];

NSString *str = @“jack”;

p1.name = str;

NSLog(@“p1.name = %@”,p1.name);

}

输出:p1.name = jack

大家思考一下,如果我现在,来1个str = @“rose”,会怎么样

int main(){

Person *p1 = [Person new];

NSString *str = @“jack”;

p1.name = str;

str = @“rose”;

NSLog(@“p1.name = %@”,p1.name);

}

输出jack

为什么,因为一开始str指向@“jack”这个常量区的字符串对象然后p1.name = str,把str的值赋给p1.name属性,这时候,p1.name指向了@“jack”这个字符串对象然后创建了1个新的字符串对象,在常量区,@“rose”,str指向了@“rose”,但是,对p1.name属性有影响吗,没有,p1.name还是指向@“jack

2.我换一种写法

int main(){

Person *p1 = [Person new];

NSMutableString *str = [NSMutableString stringWithFormat:@“jack”];

p1.name = str;

NSLog(@“p1.name = %@”,p1.name);

}

大家思考,打出来的是什么,是不是jack

输出:jack

如果,我来一个

[str appendString:@“rose”];

这个时候,会怎么样呢

int main(){

Person *p1 = [Person new];

NSMutableString *str = [NSMutableString stringWithFormat:@“jack”];

p1.name = str;

[str appendString:@“rose”];

NSLog(@“p1.name=%@”,p1.name);

输出:jackrose

为什么,因为这个时候,创建的是NSMutableString对象,是存储堆区的,

这个时候,[str appendString:@“rose”];

是不是直接就改它了啊,

直接里面追加可以,会不会创建新的对象,不会

所以p1的下划线name字符串,也是jackrose了

3.很明显,大家思考一下,我希不希望有这种效果,肯定不希望

你看,这个时候,我先把这个字符串赋给了p1的name属性,是不是,

这个时候,我再去改这个字符串,我希不希望再去影响p1的name呢

不希望

我希望它不影响

需求:将str赋值给p1的name属性以后,再修改str的值,不要影响p1的name

而现在事实上,有没有影响啊,影响了,我希望它不影响,大家思考一下,我可以怎么做

赋值的时候,我可以怎么赋值,把str这个字符对象copy一份,

p1.name = str;

这句话,在赋值的时候,可以怎么赋值,把str这个字符串对象copy一份

然后p1.name指向这个新的对象

这个时候,你去改str改的是谁,是不是拷贝前的那个对象,影不影响p1.name指向的新对象,不影响,

5.解决方案:在setter方法赋值的时候,将传进来的对象先拷贝1份,

我可以怎么写这个setter方法

– (void)setName:(NSString *)name{

_name = [name copy];

}

我这么写以后,一样的代码,在main.m文件

int main(){

Person *p1 = [Person new];

NSMutableString *str = [NSMutableString stringWithFormat:@“jack”];

p1.name = str;

[str appendString:@“rose”];

NSLog(@“p1.name = %@”,p1.name);

输出:p1.name = jack

为什么, 因为

p1.name = str;

这句话,是不是把str的值赋给p1的name属性啊,

是不是也就会调用p1的setter方法

那个方法怎么做,

是不是调用传进来的对象的copy方法,这个时候拷贝,是深拷贝还是浅拷贝

深拷贝,因为这是个NSMutableString嘛

copy一个对象,然后这个对象的地址,是1个新的地址了吧

再把这个copy出来的对象的地址,赋给p1的_name属性吧

所以,这个时候,str和_name是不是指向同1个对象,不指向同1个对象了

所以这个时候,你去修改str,改成@“jackrose”,

对这个p1的_name属性有影响吗,没有

所以,解决方案简单,就是字符赋值的时候,把这个字符串拷贝一份,就可以了

6.那问题来了,

也就是说,当属性的类型,是NSString类型的时候,我们这个地方就不应该,不能直接赋值了吧

– (void)setName:(NSString *)name{

_name = name;

}

应该怎么办,应该把传进来的对象copy一份啊

– (void)setName:(NSString *)name{

_name = [name copy];

}

那我在写@property的时候,如何生成代码,是去copy呢

对,就把参数写copy就可以了

@property(nonatomic,copy)NSString *name;

比如,这个人有国籍是不是,我来1个国籍属性

@property(nonatomic,copy)NSString *country;

这个时候,我写个copy的话,它是什么效果

生成的setter方法里面,就是怎么生成的啊,

对,把传进来的字符copy一份,然后再赋值的

好了,这就是我们这个结论了

二、结论:

无论在MRC,还是在ARC下面啊,如果属性的类型是NSString类型的,@property的参数使用copy

三、有没有问题

1.我下面这个setter方法的参数是NSString类型

– (void)setName:(NSString *)name

{

_name = [name copy];

}

我传进来的对象是个什么对象,我传进来的对象是个NSMutableString对象

然后这个NSString类型的指针,是不是指向了1个NSMutableString对象啊,

NSString *name = [NSMutableString new];

那我现在通过这个name,调用copy

_name = [name copy];

调用的是NSString的copy,还是NSMutableString的copy

NSMutableString的copy啊

因为我们说过,这句话什么意思

_name = [name copy];

调用这个name指针指向的对象的copy方法嘛

而此时此刻,这个name指针指向的对象是个什么对象,NSMutableString对象嘛

所以这个时候,就是个深拷贝嘛

有人说,万一我传进来的,它不是一个NSMutableString呢,

而是1个NSString呢

那就浅拷贝嘛

这个时候,浅拷贝有没有影响,没有影响,因为它一旦修改,一修改,它就会立即的重新创建1个对象,是不是,

所以,最重要的结论,

无论在MRC还是在ARC下,如果属性的类型是NSString类型的,那么@property参数使用copy

原文地址:https://blog.csdn.net/madoca/article/details/128178399

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_29278.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注