• Objective-C:OC内部可变对象和不可变对象的深(复制)拷贝问题思考:


    OC内部:可变对象和不可变对象的深(复制)拷贝问题思考:

     
    不可变对象:
     例如NSString对象,因为NSString对象是常量字符串,所以,不可以更改其内容,但是可以修改指向该字符串的指针指向。当对NSString对象做深拷贝时,如果是copy复制方式,其实就是浅复制,只是复制了同一个对象的指针;如果是mutableCopy复制方式,系统会分配一个新的内存空间用来存放复制出来的NSMutableString对象,此时地址是新的,内容是一样的,他们正在被不同的实例变量字符串指针指着。
     
    可变对象:
      例如NSMutableString对象,因为NSMutableString对象是可变字符串,所以,可以改变其内容。当NSMutableString对象做深拷贝时,系统会分配一个新的内存空间用来存放复制出来的NSMutableString对象,此时地址是新的,内容是一样的,他们正在被不同的实例变量字符串指针指着。
     
    总结:对于系统的非容器类对象,我们可以认为,如果对一不可变对象复制,copy是指针复制(浅拷贝)和mutableCopy就是对象复制(深拷贝)。
     
             如果是对可变对象复制,都是深拷贝,但是copy返回的对象是不可变的的。

     1:对于不可变对象,copy都是浅复制,即指针复制。mutableCopy 都是Alloc一个新对象返回。
    2:对于可变对象,copy和mutableCopy都是Alloc新对象返回。
    3:不论是可变还是不可变对象,copy返回的对象都是不可变的,mutableCopy返回的对象都是可变的。

    4:容器类对象,不论是可变的还是不可变的,copy,mutableCopy返回的对象里所包含的对象的地址和之前都是一样 的,即容器内对象都是浅拷贝。

       一、不可变对象的深复制

     1 //  Person.h
     2 //  测试
     3 //
     4 //  Created by ma c on 15/8/15.
     5 //  Copyright (c) 2015年. All rights reserved.
     6 //
     7 
     8 #import <Foundation/Foundation.h>
     9 
    10 @interface Person : NSObject<NSCopying>
    11 @property(nonatomic,copy)NSString *name;
    12 -(id)initWithName:(NSString *)name;
    13 -(void)print;
    14 @end
     1 //  Person.m
     2 //  测试
     3 //
     4 //  Created by ma c on 15/8/15.
     5 //  Copyright (c) 2015年. All rights reserved.
     6 //
     7 
     8 #import "Person.h"
     9 
    10 @implementation Person
    11 -(id)initWithName:(NSString *)name
    12 {
    13     self = [super init];
    14     if(self)
    15     {
    16         _name = [name mutableCopy]; //不可变深复制mutableCopy
    17         //_name = [name copy];//不可变深复制copy
    18     }
    19     return self;
    20 }21 -(id)copyWithZone:(NSZone *)zone
    22 {
    23     return [[Person alloc]initWithName:_name];
    24 }
    25 @end

        主函数测试

    1. //  main.m
    2. //  测试
    3. //
    4. //  Created by ma c on 15/8/15.
    5. //  Copyright (c) 2015年. All rights reserved.
    6. //
    1. #import <Foundation/Foundation.h>
    2. #import "Person.h"
    3. int main(int argc, const char * argv[])
    4. {
    5.     @autoreleasepool
    6.     {
    7.         NSMutableString *name = [NSMutableString stringWithString:@"Jobs"];
    8.         Person *p1 = [[Person alloc]initWithName:name];
    9.         NSLog(@"%@----%p",name,p1.name);
    10.         
    11.         Person *p2 = [p1 copy];
    12.         NSLog(@"%@----%p",name,p2.name);
    13.         
    14.         [name appendString:@"Tom"];
    15.         Person *p3 = [[Person alloc]initWithName:name];
    16.         NSLog(@"%@----%p",name,p3.name);
    17.         
    18.         Person *p4 = [p3 copy];
    19.         NSLog(@"%@----%p",name,p4.name);
    20.     }
    21.     return 0;
    22. }

        测试结果如下:

    
    

    2015-08-15 22:14:33.544 测试[2042:151149] Jobs----0x100206d10

    
    

    2015-08-15 22:14:33.545 测试[2042:151149] Jobs----0x100300360

    
    

    2015-08-15 22:14:33.545 测试[2042:151149] JobsTom----0x100300410

    
    

    2015-08-15 22:14:33.545 测试[2042:151149] JobsTom----0x100400010

    
    

    Program ended with exit code: 0

    
    以上结果为mutableCopy深复制的结果:复制后一样的内容,可是各自所在的地址值是不同的,说明了系统为新创建的对象开辟了内存,这就是真正意义的深复制。
    
    

    2015-08-15 22:15:08.773 测试[2050:151390] Jobs----0x100206d10

    
    

    2015-08-15 22:15:08.774 测试[2050:151390] Jobs----0x100206d10

    
    

    2015-08-15 22:15:08.775 测试[2050:151390] JobsTom----0x100207810

    
    

    2015-08-15 22:15:08.775 测试[2050:151390] JobsTom----0x100207810

    
    

    Program ended with exit code: 0

    
    以上结果为copy深复制结果,可以看出复制后一样的内容,可是它们的地址值是一样,说明了这并不是真正意义的深复制,而是假深复制,即最终结果是只是复制了指针。

      二、可变对象的深复制

     1 //  Person.h
     2 //  测试
     3 //
     4 //  Created by ma c on 15/8/15.
     5 //  Copyright (c) 2015年. All rights reserved.
     6 //
     7 
     8 #import <Foundation/Foundation.h>
     9 
    10 @interface Person : NSObject<NSCopying>
    11 @property(nonatomic,copy)NSMutableString *name;
    12 -(id)initWithName:(NSMutableString *)name;
    13 -(void)print;
    14 @end
     1 //  Person.m
     2 //  测试
     3 //
     4 //  Created by ma c on 15/8/15.
     5 //  Copyright (c) 2015年. All rights reserved.
     6 //
     7 
     8 #import "Person.h"
     9 
    10 @implementation Person
    11 -(id)initWithName:(NSMutableString *)name
    12 {
    13     self = [super init];
    14     if(self)
    15     {
    16         //_name = [name copy];//可变深复制copy
    17         _name = [name mutableCopy];//可变深复制mutableCopy
    18     }
    19     return self;
    20 }
    21 -(id)copyWithZone:(NSZone *)zone
    22 {
    23     return [[Person alloc]initWithName:_name];
    24 }
    25 @end

      主函数测试

     1 //  main.m
     2 //  测试
     3 //
     4 //  Created by ma c on 15/8/15.
     5 //  Copyright (c) 2015年. All rights reserved.
     6 //
     7 
     8 #import <Foundation/Foundation.h>
     9 #import "Person.h"
    10 int main(int argc, const char * argv[])
    11 {
    12     @autoreleasepool
    13     {
    14         NSMutableString *name = [NSMutableString stringWithString:@"Jobs"];
    15         
    16         Person *p1 = [[Person alloc]initWithName:name];
    17         NSLog(@"%@----%p",name,name);
    18         NSLog(@"%@----%p",p1.name,p1.name);
    19 
    20     }
    21     return 0;
    22 }

        测试结果如下:

    2015-08-15 21:54:12.110 测试[1973:145250] Jobs----0x1001002d0
    2015-08-15 21:54:12.111 测试[1973:145250] Jobs----0x100106c90
    Program ended with exit code: 0
    
    以上结果为可变对象的复制,采用copy复制时,复制出的内容是一样的,但是它们的地址值是不相同的,所以这是真正意义的深复制。
    2015-08-15 21:56:05.744 测试[1981:145831] Jobs----0x1001147a0
    2015-08-15 21:56:05.745 测试[1981:145831] Jobs----0x100114a40
    Program ended with exit code: 0
    
    以上结果为可变对象的复制,采用mutableCopy复制时,复制出的内容也是一样的,但是它们的地址值也是不同的,这也是真正意义的深复制。
  • 相关阅读:
    JUnitBeforeClass、AfterClass、Before、After示例
    4 jquery中dom操作和事件的实例学习访yahoo邮箱登录框的提示效果
    2 jquery 强大的选择器
    3 jquery对象和dom对象的相互转换
    开博第一篇
    转载notepad++ zendcoding使用
    轻描淡写的日子
    测试
    BPMN中的任务(task)介绍
    Google App Engine正式对Java进行支持
  • 原文地址:https://www.cnblogs.com/XYQ-208910/p/4733106.html
Copyright © 2020-2023  润新知