美文网首页
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属性

    1、拷贝的目的: 产生一个副本对象,跟源对象互不影响修改了源对象,副本对象没有任何影响修改副本对象,源对象没有任何...

  • 重拾iOS-copy

    关键词: , , , , 面试题:1)什么是深拷贝什么是浅拷贝?2)对可变对象进行copy是深拷贝还是浅拷贝?3)...

  • iOS-copy关键字

    copy关键字主要有两个要注意的地方,一个是何时使用copy关键字声明;第二个问题是深拷贝与浅拷贝的问题。 什么时...

  • iOS-copy/mutableCopy、深复制/浅复制

    copy/mutablecopy 使用copy或者mutablecopy方法可以创建一个对象的副本 copy:需要...

  • iOS-copy strong 可变 不可变 深浅拷贝

    NSString内存分配情况 可变 不可变: NSString 不可变是说它指向的不可变,重新赋值NSString...

  • 成员属性、静态属性、私有属性、原型属性

    一、成员属性和成员方法在构造函数中,通过this.属性声明,或者实例化出对象后,通过“对象.属性”追加的,都属于成...

  • swift 属性(存储属性、计算属性、懒加载属性、类型属性)

    存储属性 存储属性:用于存储一个常量或变量 结构体实例赋值给常量,该实例属性不能被修改(因为结构体属于值类型,当值...

  • jQuery属性操作

    attr(属性名,属性值)操作所有属性 removeAttr(属性名) prop(属性名,属性...

  • 依赖属性|简单属性|附加属性

    依赖属性 简单理解就是属性,支持继承,比如 Window 有 Font 属性,Button 也有 Font 属性,...

  • attribpromote

    属性创建。 属性名称,属性类别,默认属性,输出属性。 属性转移,atteibutrename. 在点属性上,现有属...

网友评论

      本文标题:iOS-copy属性

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