当前位置:网站首页>[OC-Foundation框架]--<Copy对象复制>
[OC-Foundation框架]--<Copy对象复制>
2022-07-06 08:50:00 【关于小司】
文章目录
copy 与 mutableCopy 方法
copy方法
copy 方法用于复制对象的副本,copy方法总返回对象的不可修改副本,即使该对象本身是可修改的
- 例如 :NSMutableString 的copy方法 返回不可修改的字符串对象
mutableCopy 方法
- mutableCopy 方法用于复制对象的可变副本,通常来说,mutableCopy 方法返回该对象可修改的副本,即使被复制的的对象是不可修改的
mutableCopy 方法 copy方法的共同特点
无论如何 copy 和 mutableCopy 返回的总是对象的副本,当程序对复制的副本进行修改时,原对象通常不会受到影响
mutableCopy和copy 程序实例
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSMutableString *book = [NSMutableString stringWithString:@"疯狂iOS勒布朗"];
NSMutableString *bookCopy = [book mutableCopy];
[bookCopy replaceCharactersInRange:
NSMakeRange (2, 3)
withString:@"Android"];
NSLog(@"book 的值:%@", book);
// 字符串副本发生了改变
NSLog(@" bookCopy的值 为 %@", bookCopy);
NSString *str = @"fkiOS";
// 赋值str(不可变子串的副本 --可变)
NSMutableString * strCopy = [str mutableCopy];
//向可变后追加字符
[strCopy appendString:@" ,org"];
NSLog(@"%@ ", strCopy);
//调用book的Copy方法返回一个不可修改副本·
NSMutableString* bookCopy2 = [book copy];
// 不可修改发生错误
//Thread 1: "Attempt to mutate immutable object with appendString:"
//注释
// [bookCopy2 appendString:@"123456"];
}
return 0;
}`在这里插入代码片`
- 调用一个方法返回一个不可修改的副本时候
//调用book的Copy方法返回一个不可修改副本·
NSMutableString* bookCopy2 = [book copy];
// 不可修改发生错误
//Thread 1: "Attempt to mutate immutable object with appendString:"
//注释
// [bookCopy2 appendString:@"123456"];
- 在上面的程序中,虽然str是不可变字符串 但是通过mutableCopy 方法依然得到依然是可变副本,因此可以对strCopy进行修改
- 虽然book是可变字符串但是调用了copy的发哦的事不可变副本 因此对bookCopy2字符串进行修改 会导致错误
NScopying 与 NSmutableCopying 协议
通过copy 与 mutableCopy 方法复制对象的副本开起来很方便
但是自定义类是否可代用copy 与 mutableCopy 方法来复制副本吗?
OC规定
- Xcode的 报错可以看出 虽然NSObject提供了copy和 mutablecopy方法 但自定义类并不能调用这两个方法来复制自身



此细节不过多赘述
深复制和浅复制
浅复制
我们来看一个简单的对于类复制的例子
定义一个FKdog对象
注意在接口部分声明协议NSCopying
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface FKdog : NSObject <NSCopying> //声明copy协议 因为是一个类
@property (nonatomic, strong) NSMutableString* name;
@property (nonatomic, assign) int age;
@end
NS_ASSUME_NONNULL_END
浅复制的实现部分
- (id)copyWithZone:(nullable NSZone *)zone {
FKdog* dog = [[[self class] allocWithZone:zone] init];
dog.name = self.name; //注意区别
dog.age = self.age;
return dog;
}
#import <Foundation/Foundation.h>
#import "FKdog.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
FKdog *d1 = [[FKdog alloc] init];
d1.name = [NSMutableString stringWithString:@"旺财"];
d1.age = 20;
FKdog *d2 = [d1 copy];
[d2.name replaceCharactersInRange:NSMakeRange(0, 2) withString:@"旺财2号"];
NSLog(@"%@, %d", d1.name, d1.age);
NSLog(@"%@, %d", d2.name, d2.age);
}
return 0;
}

关于浅复制
上面调用了dog1 的copy方法复制了一个副本,并将副本复制dog2变量,接下来修改了dog2的name属性 输出
发现我们只是修改了dog2的name 但是为何dog1 也变化了

注意,name是一个指针类型的变量,该变量里存放的字符串的地址,并不是字符串本身,这样赋值的效果是dog的name 属性与被复制对象self的name属性指向同一个字符串 而age变量不困如何改变 dog1都不会变
(我们把dog2的年龄改为100 发现dog1 还是20)如下
2022-05-25 19:19:55.815766+0800 OC-copy[15837:2289009] 旺财2号, 20 2022-05-25 19:19:55.815971+0800 OC-copy[15837:2289009] 旺财2号, 100 Program ended with exit code: 0我们可以得出结论 只要是浅复制 只要是指针类型的属性
改变任意一个都会改变另一个 的属性值

深复制
深复制则会采取与之不同的方式 神复制不仅会复制对象本身,还会递归复制每个指针类型的属性 直到两个对象没有任何的公共部分 将实现NSCopy协议的修改即可实现深复制
浅复制到深复制
#import "FKdog.h"
@implementation FKdog
- (id)copyWithZone:(nullable NSZone *)zone {
FKdog* dog = [[[self class] allocWithZone:zone] init];
dog.name = [self.name mutableCopy];
//修改如下在指针类型变量的self之加上
//mutableCopy
dog.age = self.age;
return dog;
}
@end

- 可以看到dog1 的指针类型name不改变
关于深复制
上面程序中并没有简单地将被复制对象的 name 属性值赋给新对象的 name 属性,而是先将原对象的 name 属性值复制了一份可变副本,再将该可变副本的值赋给新对象的name 属性。
这样就保证了原 FKDog 对象与新的 FKDog 对象之问没有任何共用的部分,这就实现了深复制。当 FKDog 实现了深复制之后,再次编译、运行上面的 程序,将可以看到两个FKDog 对象之问没有任何关联,当一个FKDog对象的name 属性值改变时,另一个 FKDog对象的 name 属性值不会受到任何影响
Foundation 框架中的类大部分都只实现了浅复制。
额外的知识增加了
对于我们的浅复制 协议实现代码
- (id)copyWithZone:(nullable NSZone *)zone {
FKdog* dog = [[[self class] allocWithZone:zone] init];
dog.name = self.name; //注意区别
dog.age = self.age;
return dog;
}
#import <Foundation/Foundation.h>
#import "FKdog.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
FKdog *d1 = [[FKdog alloc] init];
d1.name = [NSMutableString stringWithString:@"旺财"];
d1.age = 20;
FKdog *d2 = [d1 copy];
[d2.name replaceCharactersInRange:NSMakeRange(0, 2) withString:@"旺财2号"];
NSLog(@"%@, %d", d1.name, d1.age);
NSLog(@"%@, %d", d2.name, d2.age);
}
return 0;
}
注意我们在给dog2赋值的时候 用的是copy方法但是我们此时的copy并没有变成可变copy 为什么dog2的name还可以被 改变呢?
-因为 我们在写NSCopying协议的时候进行了直等于符号 相当于我们在内部重写了copy方法这样子copy方法就会改变了
如果把方法变成这样子
dog.name = [self.name copy]; //注意区别
那么系统就会提示 dog2是不可修改的数据了
边栏推荐
- Introduction to the differences between compiler options of GCC dynamic library FPIC and FPIC
- The problem and possible causes of the robot's instantaneous return to the origin of the world coordinate during rviz simulation
- Charging interface docking tutorial of enterprise and micro service provider platform
- The network model established by torch is displayed by torch viz
- Generator parameters incoming parameters
- Super efficient! The secret of swagger Yapi
- pytorch训练好的模型在加载和保存过程中的问题
- Variable length parameter
- LeetCode:162. 寻找峰值
- vb.net 随窗口改变,缩放控件大小以及保持相对位置
猜你喜欢

Image, CV2 read the conversion and size resize change of numpy array of pictures

个人电脑好用必备软件(使用过)

Double pointeur en langage C - - modèle classique

广州推进儿童友好城市建设,将探索学校周边200米设安全区域

JVM quick start

The ECU of 21 Audi q5l 45tfsi brushes is upgraded to master special adjustment, and the horsepower is safely and stably increased to 305 horsepower

C语言深度解剖——C语言关键字

ESP8266-RTOS物联网开发

The ECU of 21 Audi q5l 45tfsi brushes is upgraded to master special adjustment, and the horsepower is safely and stably increased to 305 horsepower

深度剖析C语言指针
随机推荐
LeetCode:221. 最大正方形
How to effectively conduct automated testing?
Roguelike game into crack the hardest hit areas, how to break the bureau?
Li Kou daily question 1 (2)
自动化测试框架有什么作用?上海专业第三方软件测试公司安利
R language ggplot2 visualization, custom ggplot2 visualization image legend background color of legend
角色动画(Character Animation)的现状与趋势
[embedded] print log using JLINK RTT
How to conduct interface test? What are the precautions? Nanny level interpretation
LeetCode:498. Diagonal traversal
TP-LINK 企业路由器 PPTP 配置
Leetcode: Sword Finger offer 42. Somme maximale des sous - tableaux consécutifs
深度剖析C语言数据在内存中的存储
Purpose of computer F1-F12
marathon-envs项目环境配置(强化学习模仿参考动作)
Guangzhou will promote the construction of a child friendly city, and will explore the establishment of a safe area 200 meters around the school
Current situation and trend of character animation
Nacos 的安装与服务的注册
Analysis of the source code of cocos2d-x for mobile game security (mobile game reverse and protection)
ROS compilation calls the third-party dynamic library (xxx.so)