• 【@property的参数copy Objective-C语言】


    一、@property的参数copy

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

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

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

    在Person.h文件中

    #import

    @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

    #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

  • 相关阅读:
    Vue组件的样式绑定和事件监听处理
    kylin-v10安装神舟通用数据库
    【函数式接口使用✈️✈️】配合策略模式实现文件处理的案例
    记录--从AI到美颜全流程讲解
    docker入门加实战—docker安装并配置阿里云加速
    二十三种设计模式全面解析-当你的对象需要知道其他对象的状态变化时,观察者模式是你的救星!
    【web前端期末大作业】基于HTML+CSS+JavaScript实现代理商销售管理系统后台(8页)
    清华大牛终于把「图解计算机网络、操作系统」学习笔记总结出来了
    【GEE笔记11】数值Number(常见指令方法4)
    信创清华同方超翔apt源(清华同方+银河麒麟V10+飞腾)
  • 原文地址:https://blog.csdn.net/madoca/article/details/128178399