当前位置:网站首页>OC--对象复制
OC--对象复制
2022-07-25 09:21:00 【山河丘壑】
文章目录
学学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代表具有映射关系的集合。
集合里只能保存对象,(指针变量)
边栏推荐
- How can technologists start their personal brand? Exclusive teaching of top five KOLs
- Numpy - 数组array的构造
- Floating point number exploration
- 多态和接口
- 【代码源】 每日一题 素数之欢(bfs)
- 一文搞懂为什么要同时重写equals方法和hashCode方法+实例分析
- MySQL的索引、视图与事务
- 作业7.15 shell脚本
- Machine learning -- detailed introduction of standardscaler (), transform (), fit () in sklearn package
- Redis string 结构命令
猜你喜欢

¥1-3 SWUST oj 942: 逆置顺序表

~2 ccf 2022-03-1 未初始化警告

idea实用tips---如今将pom.xml(红色)改为pom.xml(蓝色)

如何将Jar包部署到服务器,注:启动命令有无nohup有很大关系
![[HCTF 2018]admin](/img/d7/f0155c72d3fbddf0a8c1796a179a0f.png)
[HCTF 2018]admin

~5 ccf 2021-12-2 序列查询新解

Swagger2 shows that there is a problem with the get interface, which can be solved with annotations

Idea practical tips --- now change pom.xml (red) to pom.xml (blue)

无法再web服务器上启动调试,web服务器未能找到请求资源

Idea hot deployment
随机推荐
数据分析之numpy基础包
Basic network knowledge
[selected] from simple to deep, you will understand MQ principles and application scenarios
Interviewer: tell me the difference between redis and mongodb? [easy to understand]
【代码源】每日一题 分割(nlogn&n解法)
[GYCTF2020]Node Game
C language and SQL Server database technology
初始Flask以及简单地上手应用
Swagger2显示get接口有问题,加注解就能解决
OverTheWire-Bandit
机器学习 —— Sklearn包中StandardScaler()、transform()、fit()的详细介绍
数据控制语言(DCL)
【代码源】 每日一题 素数之欢(bfs)
&lt;T&gt;泛型方法演示
【代码源】每日一题 国家铁路
Go foundation 2
前台页面打印
cf #785(div2) C. Palindrome Basis
uni-app小程序如何自定义标题内容(如何解决小程序标题不居中)
Redis string 结构命令