OC--对象复制


学学copy和mutableCopy方法

提示:以下是本篇文章正文内容,下面案例可供参考

一、copy和mutableCopy

copy方法用于复制对象的副本
即使对象本身可以被修改,copy方法也会返回一个不可修改的副本

mutableCopy方法用于复制对象的可变副本
即使对象本身是不可修改的,mutableCopy也会返回一个可以修改的副本
程序调用NSString的mutableCopy方法时,将会返回一个NSMutableString对象。

copy和mutableCopy方法返回的总是原有对象的副本,当程序对复制的副本进行修改时,原有对象不会受到影响

函数测试:

#import<Foundation/Foundation.h>
int main(){
    @autoreleasepool {
        NSMutableString* person=[NSMutableString stringWithString:@"娜娜"];
       //使用nutableCopy函数,得到的对象可以被修改
        NSMutableString* personcopy=[person mutableCopy];
        [personcopy replaceCharactersInRange:NSMakeRange(0,1) withString:@"nuonuo"];
        NSLog(@"person=%@",person);
        NSLog(@"persοncοpy=%@",personcopy);
        NSString* str=@"神奇";
        //同上可被修改
        NSMutableString* strCopy=[str mutableCopy];
        [strCopy appendString:@"nuonuo"];
        NSLog(@"%@",strCopy);
        //使用copy方法,所以personCopy2不能被修改,所以下边的程序语句报错
        NSMutableString* personCopy2=[person copy];
        //[personCopy2 appendString:@"挪"];
    }
}

在这里插入图片描述
当加上最下边的一句代码时,会看到如下报错:这是因为personCopy2的值时不能修改的。
在这里插入图片描述

二、NSCopying和NSMutableCopying协议

1.自定义类的copy和mutableCopy复制

类的接口部分


#import <Foundation/Foundation.h>

@interface Person:NSObject
@property(nonatomic, strong)NSMutableString* name;
@property(nonatomic,assign)int age;
@end

类的实现部分

#import"FK.h"
@implementation Person
@synthesize name;
@synthesize age;
@end

测试

#import<Foundation/Foundation.h>
#import"FK.h"
int main(){
    @autoreleasepool {
        Person* person1=[Person new];
        person1.name=[NSMutableString stringWithString:@"娜娜"];
        person1.age=29;
        Person* person2=[person1 copy];
    }
}


运行结果如下:
在这里插入图片描述
在这里插入图片描述
类的实现部分:

#import"FK.h"
@implementation Person
@synthesize name;
@synthesize age;
-(id)copyWithZone:(NSZone*)zone
{
    NSLog(@"heihei");
    Person* person=[[[self class]allocWithZone:zone]init];
    person.name=self.name;
    person.age=self.age;
    return person;
}
@end

测试:

#import<Foundation/Foundation.h>
#import"FK.h"
int main(){
    @autoreleasepool {
        Person* person1=[Person new];
        person1.name=[NSMutableString stringWithString:@"娜娜"];
        person1.age=29;
        Person* person2=[person1 copy];
        person2.name=[NSMutableString stringWithString:@"heihei"];
        person2.age=31;
        NSLog(@"%@",person1.name);
        NSLog(@"%d",person1.age);
        NSLog(@"%@",person2.name);
        NSLog(@"%d",person2.age);
    }
}

在这里插入图片描述
在这里插入图片描述

2.深复制和浅复制

类的接口:

#import <Foundation/Foundation.h>

@interface Person:NSObject
@property(nonatomic, strong)NSMutableString* name;
@property(nonatomic,assign)int age;
@end

类的实现:

#import"FK.h"
@implementation Person
@synthesize name;
@synthesize age;
-(id)copyWithZone:(NSZone*)zone
{
    NSLog(@"heihei");
    Person* person=[[[self class]allocWithZone:zone]init];
    person.name=self.name;
    person.age=self.age;
    return person;
}
@end

测试:

#import<Foundation/Foundation.h>
#import"FK.h"
int main(){
    @autoreleasepool {
        Person* person1=[Person new];
        person1.name=[NSMutableString stringWithString:@"娜娜"];
        person1.age=29;
        Person* person2=[person1 copy];
        [person2.name replaceCharactersInRange:NSMakeRange(0,1) withString:@"nuo"];
        NSLog(@"%@",person2.name);
        NSLog(@"%@",person1.name);
    }
}

结果:
在这里插入图片描述
我们只是修改了person2,为什么person1也改变了?
程序创建了第一个person对象,并使用person1的指针指向它,如图:
在这里插入图片描述
这是我们的对象复制的代码:
在这里插入图片描述
person代表被复制出来的对象,此时的name只是一个指针对象,该变量中存放的只是字符串的地址,并不是字符串本身。==这样赋值的效果是让person的name属性与被复制对象的name指向同一个字符串。
在这里插入图片描述

此时的person1和person2分别指向老公不同的person对象。但这两个对象的name的属性都是指针。而且指向同一个NSMutableString对象。这样当我们修改其中一个对象的属性值时,另一个对象的name值也会改变
对于这种复制方式,当对象的属性是指针变量是,如果程序只是复制该指针的地址,而不是复制指针所指向的对象,这种复制方式就称为浅复制
我们修改类的实现部分:

#import"FK.h"
@implementation Person
@synthesize name;
@synthesize age;
-(id)copyWithZone:(NSZone*)zone
{
    NSLog(@"heihei");
    Person* person=[[[self class]allocWithZone:zone]init];
    person.name=[self.name mutableCopy];
    person.age=self.age;
    return person;
}
@end

为什么这次两个对象的值又不一样了?
在这里插入图片描述
我们这次采用的复制方式为深复制,深复制本身不仅复制对象本身,而且会递归复制每隔指针类型的属性,直到两个对象没有任何共用的部分。修改类的实现部分即可实现深复制。
一般来说,深复制的实现难度大,尤其是当该对象包含大量的指针类型属性时。如果某些属性所引用的对象再次包含指针类型的属性,那么深复制会更复杂。
一般来说,Foundation框架中的大部分类都只实现了浅复制

三、setter方法的复制选项

1.什么时候使用?

前面介绍setter和getter方法时提到可以使用copy指示符。

类的接口:

#import <Foundation/Foundation.h>

@interface Item :NSObject
@property(nonatomic, copy)NSMutableString* name;
@end

类的实现:

#import"FK.h"
@implementation Item
@synthesize name;
@end

测试:

#import<Foundation/Foundation.h>
#import"FK.h"
int main(){
    @autoreleasepool {
        Item* item=[Item new];
        item.name=[NSMutableString stringWithString:@"nuonuo"];
        [item.name appendString:@"magic"];
    }
}

这是代码运行结果:
在这里插入图片描述
这段报错提示不允许修改name的属性值,是因为程序定义name时调用了copy指示符,该指示符调用setName时,程序实际上会使用参数的副本对name实例变量赋值。
copy方法默认是复制该对象的不可变副本,虽然程序传入的是NSMutableString,但程序调用该参数的copy方法得到的是不可变副本。因此name变量仍然是不可变字符串。

四、Objective-C集合概述

OC的集合类可以用于存储多个数量不等的对象,并实现常用的数据结构。OC的集合大概可以分为NSArray,NSSet,NSDictionary三种。NSArray代表有序,可重复的集合。NSSet代表无需,不可重复的集合,NSDictionary代表具有映射关系的集合。
集合里只能保存对象,(指针变量)

  • 8
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

山河丘壑

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值