objective-c(Copy):

浅拷贝:即是地址拷贝,并不产生新的对象,而是对原对象的引用计数值加1.
深拷贝:即是对象拷贝,产生新的对象副本,计数器为1.
//mutableCopy
//对于mutableCopy,返回的一定是可变类型。
//对于 mutableCopy,都是深拷贝:对象的拷贝,产生新的对象
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
    @autoreleasepool {
  
      // NSString *str=[[NSString alloc]initWithFormat:@"abcd"];
    NSMutableString *str = [[NSMutableString alloc] initWithFormat:@"abcd"];
            //产生了一个新的对象 计数器为1 源对象的计数器不变
            //NSMutableString *str2=[str mutableCopy];
    NSString *str2 = [str mutableCopy];
            //输出二者的地址,二者的地址是不同的
            NSLog(@"str --> %p",str);
            NSLog(@"str2 --> %p",str2);
    }
    return 0;
}
//copy
//对于copy,返回的一定是不可变类型;
//如果是 NSString ---> NSString;则是浅拷贝;
//如果是 NSMutableString ---> NSString、 NSString --->NSMutableString、NSMutableString ---> NSMutableString;则是深拷贝。
// 注:只有一种情况下是发生浅拷贝:不可变对象复制到不可变对象。除了以上这种情形外,其他都是深拷贝。
//浅拷贝:指针拷贝 不会产生新的对象,源对象计数器加1
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
    @autoreleasepool {
       
            NSString *str=[[NSString alloc]initWithFormat:@"abcd"];
            //因为NSString对象本身就不可变,所以并没产生新的对象,而是返回对象本身,会做一次retain操作,所以源对象也会retain
            NSString *str2=[str copy];
                        //输出二者的地址,二者的地址是相同的
            NSLog(@"str --> %p",str);
            NSLog(@"str2 --> %p",str2);
        }
    return 0;
}
//深拷贝
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
    @autoreleasepool {
       
    NSMutableString *str=[[NSMutableString alloc]initWithFormat:@"abcd"];
               //会产生一个新的对象计数器1
    NSString *str2=[str copy];
               //输出二者的地址,二者的地址是不同的
    NSLog(@"str -->%p",str);
    NSLog(@"str2 -->%p",str2);
            }
    return 0;
}
//对于自定义对象的Copy:该类必须实现NSCopying协议,重写 copyWithZone 方法。
//对于自定义对象的mutableCopy:必须实现 NSMutableCopying 协议,重写 mutableCopyWithZone 方法。
//在NSCopying协议中,其实只有一个协议方法
{@protocol NSCopying
- (id)copyWithZone:(NSZone *)zone;
@end}
//main.m
#import <Foundation/Foundation.h>
#import "Person.h"
int main(int argc, const char * argv[]) {
    @autoreleasepool {
       
        Person *p1 = [[Person alloc] initWithAge:12 andName:@"qwe"];
        Person *p2 = [p1 copy];
       
        NSLog(@"p1--->%p",p1);
        NSLog(@"p2--->%p",p2);
    }
    return 0;
}
//person.h
#import <Foundation/Foundation.h>

@interface Person : NSObject
@property(nonatomic,assign)int age;
@property(nonatomic,copy) NSString *name;
-(id)initWithAge:(int)newAge andName:(NSString *)newName;
@end
//person.m
#import "Person.h"

@implementation Person
-(id)initWithAge:(int)newAge andName:(NSString *)newName{
    self = [super init];
    if(self){
        self.age = newAge;
        self.name = newName;
    }
    return self;
}
-(id)copyWithZone:(NSZone *)zone;{
    Person *person =[[[self class] allocWithZone:zone] initWithAge:self.age andName:self.name];
    return person;
}
@end
//加入对于某些自定义对象是不可变的,
//-(id)copyWithZone:(NSZone *)zone{
//return self;
//}
//这样,输出的两个对象的地址就是相同的了。
 

posted on 2015-11-06 16:17  清清杨  阅读(114)  评论(0编辑  收藏  举报

导航