一、@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进行投诉反馈,一经查实,立即删除!
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。