美文网首页
iOS-copy属性

iOS-copy属性

作者: Jerky_Guo | 来源:发表于2018-07-16 16:19 被阅读7次

    1、拷贝的目的:

    • 产生一个副本对象,跟源对象互不影响
    • 修改了源对象,副本对象没有任何影响
    • 修改副本对象,源对象没有任何影响

    在iOS中,最常用的对象,比如:NSString、NSArray、NSDictionary、NSData、NSSet都具有copy功能。
    iOS提供了两个拷贝方法:

    • copy:不可变拷贝,产生不可变副本
    • mutableCopy:可变拷贝,产生可变副本

    2、深拷贝、浅拷贝

    • 深拷贝:内容拷贝,有产生新对象
    • 浅拷贝:指针拷贝,没有产生新对象

    我们对一个NSString进行copymutableCopy

            NSString *str = @"test";
            NSString *str1 = [str copy];
            NSMutableString *str2 = [str mutableCopy];
            
            NSLog(@"str=%@, str1=%@, str2=%@", str, str1, str2);
            NSLog(@"str=%p, str1=%p, str2=%p", str, str1, str2);
    

    上述代码控制台输出结果如下:

    str=test, str1=test, str2=test
    str=0x100001040, str1=0x100001040, str2=0x10062a900
    

    从上面的输出结果可以看出,通过copymutableCopy都能够获取到str字符串的值,但是从内存地址可以看出,通过copy出来的内存地址和源对象相同,通过mutableCopy出来的内存地址和源对象不同。我们把内存地址发生改变的copy操作叫做深拷贝,又称内容拷贝;反之,内存地址没有发生的copy操作叫做浅拷贝,又称指针拷贝。

    我们再对一个NSMutableString进行copymutableCopy

            NSMutableString *str =[[NSMutableString alloc] initWithString:@"test"];
            NSString *str1 = [str copy];
            NSMutableString *str2 = [str mutableCopy];
            
            NSLog(@"str=%@, str1=%@, str2=%@", str, str1, str2);
            NSLog(@"str=%p, str1=%p, str2=%p", str, str1, str2);
    

    上述代码控制台输出结果如下:

    str=test, str1=test, str2=test
    str=0x100459f50, str1=0x7473657445, str2=0x100459fa0
    

    从上面的输出结果可以看出,通过copymutableCopy都能够获取到str字符串的值,但是从内存地址可以看出,通过copymutableCopy出来的内存地址和源对象不同。所以可变字符串拷贝出来的对象都是深拷贝
    从上面的两个代码实例可以看出:

    • 对于不可变字符串,通过copy操作出的对象仅仅是浅拷贝,即指针拷贝;通过mutableCopy操作出的对象是深拷贝,即内容拷贝
    • 对于可变字符串,不论是copy还是mutableCopy操作出来的对象,都是深拷贝,即内容拷贝

    对于NSArray、NSDictionary、NSData、NSSet使用copymutableCopy,跟NSString没有太大区别。

    3、自定义对象实现copy

    创建一个JKPerson对象,继承于NSObject

    // JKPerson.h文件
    
    #import <Foundation/Foundation.h>
    
    @interface JKPerson : NSObject
    @property (nonatomic, copy) NSString *name;
    @property (nonatomic, assign) int age;
    @end
    
    // ViewController.m
    JKPerson *person = [[JKPerson alloc] init];
    person.name = @"Jack";
    person.age = 19;
    JKPerson *person1 = [person copy];
    

    JKPerson.m文件什么都没实现
    运行程序会发现崩溃了

    崩溃信息
    我们会发现JKPerson类找不到copyWithZone:方法,所以对于自定义copy我们得重写copyWithZone:方法,但是要这个类遵循NSCopying协议
    修改后代码如下
    // JKPerson.h文件
    @interface JKPerson : NSObject <NSCopying>
    @property (nonatomic, copy) NSString *name;
    @property (nonatomic, assign) int age;
    @end
    
    //  JKPerson.m
    @implementation JKPerson
    
    - (id)copyWithZone:(NSZone *)zone {
        JKPerson *person = [[JKPerson allocWithZone:zone] init];
        person.name = self.name;
        person.age = self.age;
        return person;
    }
    - (NSString *)description {
        return [NSString stringWithFormat:@"name = %@, age = %d", self.name, self.age];
    }
    @end
    
     // ViewController.m
    JKPerson *person = [[JKPerson alloc] init];
    person.name = @"Jack";
    person.age = 19;
    JKPerson *person1 = [person copy];
    NSLog(@"perosn : %@, person1 : %@", person, person1);
    NSLog(@"perosn : %p, person1 : %p", person, person1);
    

    控制台输出结果如下图


    自定义copy输出结果

    从上图输出结果可以看出,person成功的将nameage属性copy到person1上。

    相关文章

      网友评论

          本文标题:iOS-copy属性

          本文链接:https://www.haomeiwen.com/subject/ztvvpftx.html