ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

OC中对象的复制:二

2021-12-18 20:02:38  阅读:175  来源: 互联网

标签:mutableCopy 对象 OC NSLog -- 复制 copy 方法


看官们,我们在前面章回中介绍了OC中对象的复制,本章回中将继续介绍这方面的知识。
在上一章回中我们介绍了什么是复制以及如何进行复制。本章回中将介绍复制背后的原理和复制操作的原则。

复制的原理

我们通过复制操作的两个方法(copy和mutableCopy)进行复制操作时本质上是在调用`copyWithZone`和`mutableCopyWithZone`这两个方法.这两个方法是`NSCopying`和`NSMutableCopying`协议中的方法,而NSObject类实现了这两个协议并且重写了协议中的这两个方法。因此,我们在自己定义的类中重写这两个方法就可以实现复制操作。如果不重写这两个方法就进行复制操作,那么会导致运行时发生异常。下面是重写方法的示例代码。
 

-(id) copyWithZone:(NSZone *)zone
{
    NSLog(@"copying");
    //给各个属性赋值
}

-(id) mutableCopyWithZone:(NSZone *)zone
{
    NSLog(@"mutable copying");
    //给各个属性赋值
}

对于OC中的类以及Foundation框架中提供的类,我们可以直接使用copy方法来实现复制操作,因为这些类已经重写了`copyWithZone`和`mutableCopyWithZone`这两个方法。

复制的原则


这里说的原则主要有两个方面,一方面指深浅复制,另一方面指新复制出来的对象是否可以被修改。

  1. 对于自定义的类,我们的原则是:使用深复制并且复制出来的新对象可以被修改。也就是说不管使用copy方法还是mutableCopy方法,复制操作都是深复制,复制出来的对象都可以被修改。
  2. 对于OC中的类,如果类的对象是不可变的(比如NSString),copy方法是浅复制,复制出来的对象不可以被修改。 mutableCopy方法是深复制,复制出来的对象可以被修改。
  3. 对于OC中的类,如果类的对象是可变的(比如NSMutableString),copy方法和mutableCopy方法都是深复制,复制出来的对象都可经被修改。


对于使用等号进行赋值操作,它相当于浅复制,不管被复制的对象是否可变,它只是复制一个引用并没有创建新的对象。

对于自定义的类,在自定义类中实现复制操作的方法时需要遵守刚才说过的原则。对于OC中的类,复制操作的方法已经实现,我们可以通过代码来验证这些方法执行的原则。下面是一个示例代码,请大家参考:
 


#include <Foundation/Foundation.h>

@interface Book : NSObject
    @property (nonatomic,readwrite,strong) NSString *name;
    @property (nonatomic,readwrite,strong) NSMutableString *group;
    @property (nonatomic,readwrite,copy) Book* test;
    @property (nonatomic,readwrite) int price;

    -(void) show;
@end

@implementation Book
    @synthesize name;
    @synthesize price;
    @synthesize group;
    @synthesize test;

    -(void) show
    {
        NSLog(@"----Book Inof----");
        NSLog(@"name: %@ -- %p",name,name);
        NSLog(@"group: %@ -- %p",group,group);
        NSLog(@"test: %@ -- %p",test,test);
        NSLog(@"price: %d" ,price);
        NSLog(@"-----------------");
    }

//自己定义copy方法,其原则是深复制。使用mutableCopy方法实现深复制
-(id) copyWithZone:(NSZone *)zone
{
    NSLog(@"copying");
    Book *obj = [[[self class] allocWithZone:zone] init];

    obj.name = [self.name mutableCopy];
    obj.group = [self.group mutableCopy];
    obj.test = [self.test mutableCopy];
    obj.price = self.price;

    return obj;
}


-(id) mutableCopyWithZone:(NSZone *)zone
{
    NSLog(@"mutable copying");
    //直接使用交类的copy原则
    // id obj = [super mutableCopy];

    //直接使用自己的copy原则
    id obj = [self copy];

    return obj;
}

@end

int main()
{
    NSString *str1 = @"abc";
    NSString *str2 = [str1 copy];
    NSString *str3 = [str1 mutableCopy];

    //NSString对象,copy方法执行浅复制,mutableCopy方法执行深复制
    NSLog(@"string1 : %@ -- %p",str1,str1);
    NSLog(@"string2 : %@ -- %p",str2,str2);
    NSLog(@"string3 : %@ -- %p",str3,str3);

    NSArray *arr1 = [NSArray arrayWithObjects:@"aa",@"bb",@"cc",nil];
    NSArray *arr2 = [arr1 copy];
    NSArray *arr3 = [arr1 mutableCopy];

    //NSArray这类不可变对象,copy方法执行浅复制,mutableCopy方法执行深复制
    NSLog(@"array1: %@ -- %p",arr1,arr1);
    NSLog(@"array2: %@ -- %p",arr2,arr2);
    NSLog(@"array3: %@ -- %p",arr3,arr3);

    NSMutableArray *mutArr1 = [NSMutableArray arrayWithObjects:@"aa",@"bb",@"cc",nil];
    NSMutableArray *mutArr2 = [mutArr1 copy];
    NSMutableArray *mutArr3 = [mutArr1 mutableCopy];

    //NSMutableArray这类可变对象,copy方法和mutableCopy方法都执行深复制
    NSLog(@"mutabArray1: %@ -- %p",mutArr1,mutArr1);
    NSLog(@"mutabArray2: %@ -- %p",mutArr2,mutArr2);
    NSLog(@"mutabArray3: %@ -- %p",mutArr3,mutArr3);


    Book *b1 = [[Book alloc] init];
    [b1 setName:@"book1"];
    [b1 setPrice:1];
    [b1 setGroup:@"group1"];
    NSLog(@"Book1 --->");
    [b1 show];
    NSLog(@"Address: %p",b1);

    Book *b2 = [[Book alloc] init];
    //设置成copy属性后会调用类的copy方法
    [b2 setTest:b1];
    NSLog(@"Book2 --->");
    [b2 show];
}


在示例代码中演示了自定义类如何通过重写copy和mutalbeCopy方法来实现复制操作.同时也通过打印对象地址的方式演示了OC中类的复制原则,我们在相关地方都添加了注释,不过还是希望大家自己动手来实践,这样可以加深对这些复制原则的理解。


最后我们对本章回的内容做一个总结:

  • 1.复制操作表面是使用i`copy`和`mutableCopy`方法实现,但是本质上是通过`copyWithZone`和`mutableCopyWithZone`这两个方法实现的;
  • 2.自定义的类中需要实现`copyWithZone`和`mutableCopyWithZone`这两个方法,不然进行复制操作时会引发运行时异常;
  • 3.OC中提供的类已经实现了`copyWithZone`和`mutableCopyWithZone`这两个方法,我们直接进行复制操作就可以;
  • 4.我们需要明白OC提供类所遵守的复制原则,同时在自定义类时需要遵守自定义类的复制原则;

看官们,本章回的内容就介绍到这里,欲知后事如何且听下回分解!

标签:mutableCopy,对象,OC,NSLog,--,复制,copy,方法
来源: https://blog.csdn.net/talk_8/article/details/121965825

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有