当前位置: 首页 > wzjs >正文

专业做网站照片蚌埠城乡建设 局网站

专业做网站照片,蚌埠城乡建设 局网站,wordpress 伪静态规则,织梦网站搜索怎么做一、copy与mutableCopy方法 copy方法用于复制对象的副本,复制下来的该副本是不可修改的,哪怕是调用NSMutableString的copy方法也不可修改。 而mutableCopy方法复制下来的副本是可修改的,即使被复制的对象原本是不可修改的。例如调用mutableCo…

一、copy与mutableCopy方法

        

copy方法用于复制对象的副本,复制下来的该副本是不可修改的,哪怕是调用NSMutableString的copy方法也不可修改。

        而mutableCopy方法复制下来的副本是可修改的,即使被复制的对象原本是不可修改的。例如调用mutableCopy方法复制NSString的,返回的是一个NSMutableString对象。

        因为以上方法返回的是原对象的副本,所以对复制的副本进行修改时,原对象通常不受影响。

 以下用代码演示copy和mutableCopy方法的功能:

#import <Foundation/Foundation.h>int main(int argc, const char * argv[]) {@autoreleasepool {//copy与mutableCopyNSMutableString *book = [NSMutableString stringWithString: @"疯狂iOS讲义"];//定义一个book字符串NSMutableString *bookCopy = [book mutableCopy];//用mutableCopy给book复制一个副本[bookCopy replaceCharactersInRange: NSMakeRange(2, 3) withString: @"Android"];//复制后的bookCopy副本是可以修改的,这里做个修改,对原字符串的值也没有影响NSLog(@"book的值为:%@",book);//原值NSLog(@"bookCopy的值为:%@",bookCopy);//副本修改后的值,没有问题NSString *str = @"fkit";//定义一个str字符串NSMutableString *strCopy = [str mutableCopy];//用mutableCopy给str复制一个副本[strCopy appendString:@".org"];//向可变字符串后面追加字符串NSLog(@"%@",strCopy);NSMutableString *bookCopy2 = [book copy];//用copy方法复制一个book的副本(这个副本不可变)[bookCopy2 appendString:@"aa"];//这里会报错,因为copy创建的副本不可变,修改了就崩了}return 0;
}

二、NSCopying和NSmutableCopying协议

当我们想将自定义类用上一节的两个方法复制副本时,我们可能会直接创建完对象后用”类名* 对象2 = [对象1 copy];“这样的格式来复制副本,但实际上直接这样复制是不对的,会报错说找不到copyWithZone:方法,mutableCopy也是一样。因此我们可以看出,自定义类是不能直接调用这两个方法来复制自身的。

        这是为什么呢?是因为当程序调用copy/mutableCopy方法复制时,程序底层需要调用copyWithZone:/mutableCopyWithZone:方法来完成复制的工作,并返回这两个方法的值。因此为了保证可以复制,需要在自定义类的接口部分声明NSCopying/NSMutableCopying协议,然后再类的实现部分增加copyWithZone:/mutableCopyWithZone:方法,因此,对自定义对象的复制应该如下所示:

接下来,我们以一个自定义的Person类为例,支持copy和mutablecopy:

#import <Foundation/Foundation.h>@interface Person : NSObject <NSCopying, NSMutableCopying>
@property (nonatomic, copy) NSString *name;
@property (nonatomic, assign) NSInteger age;
@end@implementation Person// 实现 copy(返回不可变副本)
- (id)copyWithZone:(NSZone *)zone {Person *copy = [[[self class] allocWithZone:zone] init];copy.name = self.name;  // NSString 默认 copycopy.age = self.age;return copy;
}// 实现 mutableCopy(返回可变副本)
- (id)mutableCopyWithZone:(NSZone *)zone {Person *copy = [[[self class] allocWithZone:zone] init];copy.name = [self.name mutableCopy];  // 注意生成可变副本copy.age = self.age;return copy;
}@end
int main(int argc, const char * argv[]) {@autoreleasepool {Person *p1 = [[Person alloc] init];p1.name = @"Tom";p1.age = 18;Person *p2 = [p1 copy];         // 调用 copyWithZonePerson *p3 = [p1 mutableCopy];  // 调用 mutableCopyWithZoneNSLog(@"原始:%@ %ld", p1.name, p1.age);NSLog(@"copy:%@ %ld", p2.name, p2.age);NSLog(@"mutableCopy:%@ %ld", p3.name, p3.age);}return 0;
}

三、深复制与浅复制

深复制和浅复制是面向对象编程中非常重要的概念。

浅复制:仅复制对象的指针地址,多个变量共享同一个对象。

深复制: 不仅复制指针,还会复制整个对象内容,使得原对象和副本完全独立。

举个例子:

NSMutableString *str1 = [NSMutableString stringWithString:@"Hello"];
NSMutableString *str2 = str1;            // 浅复制(赋值)
// 修改 str1,str2 也变了
[str1 appendString:@" World"];

浅复制与深复制的区别:

浅复制:

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

深复制:

#import "FKDog.h"@implementation FKDog@synthesize name;
@synthesize age;- (id) copyWithZone:(NSZone *)zone {NSLog(@"--执行copyWithZone--");FKDog *dog = [[[self class] allocWithZone:zone] init];dog.name = [self.name mutableCopy];//在这个地方与浅复制不同dog.age = self.age;return dog;
}@end

因此总而言之,浅拷贝就是创建一个副本,对内存地址的复制。深拷贝就是创建一个副本,对内容完全复制。原始对象与副本对象内存地址不同。

按照类型说明:

非容器类对象的深拷贝与浅拷贝

不可变字符串
int main(int argc, const char * argv[]) {@autoreleasepool {NSString* str1 = @"dddddd";NSString* str2 = [str1 copy];NSString* str3 = [str1 mutableCopy];NSMutableString* str4 = [str1 copy];NSMutableString* str5 = [str1 mutableCopy];NSLog(@"str1:%p", str1);NSLog(@"str2:%p", str2);NSLog(@"str3:%p", str3);NSLog(@"str4:%p", str4);NSLog(@"str5:%p", str5);}return 0;
}

得出结论: 字符串常量,只要是copy就是浅拷贝,mutableCopy是深拷贝。tips:我们用NSString stringWithstring 方式创建的是一个常量区字符串。

可变类型字符串 
int main(int argc, const char * argv[]) {@autoreleasepool {NSMutableString* str1 = [NSMutableString stringWithString:@"helloworld"];NSMutableString* str2 = [str1 copy];NSMutableString* str3 = [str1 mutableCopy];NSString* str4 = [str1 copy];NSString* str5 = [str1 mutableCopy];NSLog(@"str1:%p", str1);NSLog(@"str2:%p", str2);NSLog(@"str3:%p", str3);NSLog(@"str4:%p", str4);NSLog(@"str5:%p", str5);}return 0;
}

 打印结果:

 这里我们发现这里的两种拷贝都是深拷贝,它都重新创建了一块新的区域储存这一部分内容

因此:

可变对象copy后的对象是不可变的,mutableCopy后的对象是可变的

对于可变对象的复制都是深拷贝

容器类对象的深浅拷贝

NSArray:NSArray 是 Objective-C 中的 不可变数组类,它在创建之后 元素数量和顺序都不能更改

NSArray *array01 = [NSArray arrayWithObjects:@"a",@"b",@"c", nil];NSArray *copyArray01 = [array01 copy];NSMutableArray *mutableCopyArray01 = [array01 mutableCopy];NSLog(@"array01 = %p,copyArray01 = %p",array01,copyArray01);NSLog(@"array01 = %p,mutableCopyArray01 = %p",array01,mutableCopyArray01);
//-----------------------------------------------------NSLog(@"array01[0] = %p,array01[1] = %p,array01[2] = %p",array01[0],array01[1],array01[2]);NSLog(@"copyArray01[0] = %p,copyArray01[1] = %p,copyArray01[2] = %p",copyArray01[0],copyArray01[1],copyArray01[2]);NSLog(@"mutableCopyArray01[0] = %p,mutableCopyArray01[1] = %p,mutableCopyArray01[2] = %p",mutableCopyArray01[0],mutableCopyArray01[1],mutableCopyArray01[2]);

可以得出下列结论:

copyArray01和array01指向的是同一个对象,包括里面的元素也是指向相同的地址。
mutableCopyArray01和array01指向的是不同的对象,但是里面的元素指向相同的对象,mutableCopyArray01可以修改自己的对象。
copyArray01是对array01的指针复制(浅复制),而mutableCopyArray01是内容复制。
所以这就是不可变的容器对象 copy是浅拷贝 mutablecopy是深拷贝

NSMutableArray:NSMutableArray 是 Objective-C 中的可变数组类,可以动态添加、删除、替换数组中的元素。

NSMutableArray *array01 = [NSMutableArray arrayWithObjects:@"a",@"b",@"c", nil];NSArray *copyArray01 = [array01 copy];NSMutableArray *mutableCopyArray01 = [array01 mutableCopy];NSLog(@"array01 = %p,copyArray01 = %p",array01,copyArray01);NSLog(@"array01 = %p,mutableCopyArray01 = %p",array01,mutableCopyArray01);NSLog(@"array01[0] = %p,array01[1] = %p,array01[2] = %p",array01[0],array01[1],array01[2]);NSLog(@"copyArray01[0] = %p,copyArray01[1] = %p,copyArray01[2] = %p",copyArray01[0],copyArray01[1],copyArray01[2]);NSLog(@"mutableCopyArray01[0] = %p,mutableCopyArray01[1] = %p,mutableCopyArray01[2] = %p",mutableCopyArray01[0],mutableCopyArray01[1],mutableCopyArray01[2]);

 我们不难发现,对于可变对象的拷贝都是一个新对象,深拷贝。

 但是,集合对象的内容复制仅限于对象本身,对象元素仍然是指针复制

用更为严谨的表达来说:

集合的 copy/mutableCopy 是容器级别的拷贝,里面的元素对象不会被复制,而是指针指向原对象。

 自定义类型的拷贝

#import <Foundation/Foundation.h>NS_ASSUME_NONNULL_BEGIN@interface Person : NSObject
@property (nonatomic, strong) NSString *name;
@property (nonatomic, assign) NSInteger age;
@endNS_ASSUME_NONNULL_END
#import "Person.h"
@interface Person()<NSCopying,NSMutableCopying>@end@implementation Person- (id)copyWithZone:(NSZone *)zone {Person *person = [[Person allocWithZone:zone]init];person.name = self.name;person.age = self.age;return person;
}- (id)mutableCopyWithZone:(NSZone *)zone {Person *person = [[Person allocWithZone:zone] init];person.name = [self.name mutableCopy]; person.age = self.age;return person;
}@end
#import <Foundation/Foundation.h>
#import "Person.h"int main(int argc, const char * argv[]) {@autoreleasepool {Person *person = [[Person alloc] init];person.name = @"Jack";person.age = 23;Person *copyPerson = [person copy]; // 深拷贝Person *mutableCopyPerson = [person mutableCopy]; // 深拷贝NSLog(@"person = %p;copyPerson = %p",person,copyPerson);NSLog(@"person = %p;mutableCopyPerson = %p",person,mutableCopyPerson);}return 0;
}

 我们可以看到无论是copy还是mutableCopy,都是深拷贝,这是因为我们本来就是使用copyWithZone和mutableCopyWithZone进行拷贝的。

容器类对象的深拷贝

1. copyItems 方法是NSArray和NSMutableArray的一个方法,用于创建一个新的数组,并对数组中的元素进行拷贝。该方法遍历原数组的每个元素,并对每个元素执行copy操作,然后将拷贝后的元素添加到新数组中。

int main(int argc, const char * argv[]) {@autoreleasepool {NSMutableString* str1;FKUser* p1 = [[FKUser alloc] initWithName:@"krystal" pass:@"12"];FKUser* p2 = [p1 copy];NSArray* ary = [NSArray arrayWithObjects:p1, p2, nil];NSArray* ary1 = [[NSArray alloc] initWithArray:ary copyItems:YES];NSLog(@"%p, %p", ary, ary1);NSLog(@"%p, %p", ary1[0], ary[0]);FKUser* p3 = ary1[0];FKUser* p4 = ary[0];NSLog(@"%p, %p", p3.name, p4.name);}return 0;
}

 我们对于数组内部的元素也进行一了一次深拷贝。这个方法实现了我们的对于容器内部的一个深拷贝。但是,要注意一个点,就是我们容器类对象中的元素是非容器类才可以实现一个复制,但是注意这里我们没有对对象进行更深一层的拷贝

如果想实现一个完全意义上的深拷贝,我们可以通过解档与归档,我也不懂。。。

为什么要按照类型说明深拷贝和浅拷贝

 一、对象的“值语义”与“引用语义”

在 Objective-C 和 Java 中,大多数对象是 引用类型,意味着变量存的是地址。

如果不区分是浅拷贝还是深拷贝,就会遇到下面的问题:

示例:浅拷贝带来的“数据共享”问题

Person *p1 = [[Person alloc] init];
p1.name = [NSMutableString stringWithString:@"Jack"];Person *p2 = p1; // 只是引用复制
[p2.name appendString:@"son"];
NSLog(@"p1.name = %@", p1.name); // ❌ 输出:Jackson,被污染了!

如果是深拷贝就不会:

Person *p2 = [p1 copy]; // p2 有自己的 name 对象

二、不同类型容器(如数组、字典)处理方式不同

NSArray 的 copy 和 mutableCopy:

  • 容器对象是新建的(浅层拷贝)

  • 但里面的元素是指针复制(浅拷贝)

这就导致:

NSMutableString *str = [NSMutableString stringWithString:@"abc"];
NSArray *arr1 = @[str];
NSArray *arr2 = [arr1 copy];[str appendString:@"def"];
NSLog(@"%@", arr2[0]); // ❌ abcdef,浅拷贝没有保护内容

如果你期望元素不被影响,就要手动执行“深拷贝”:

NSMutableArray *arrDeepCopy = [[NSMutableArray alloc] initWithArray:arr1 copyItems:YES];

 三、性能与内存控制的考虑

  • 浅拷贝速度快,节省内存(适合临时引用、只读场景)

  • 深拷贝安全性高,但代价是开销大(创建副本、递归 copy)

所以,只有明确区分类型的拷贝方式,才能:

  • 在 需要保护数据 时使用深拷贝

  • 在 优化性能 时使用浅拷贝

四、合理设计类的拷贝行为(实现 NSCopying 协议)

当你写一个类(如 Person)时,你要决定:

  • 哪些属性需要深拷贝(如 NSString, NSArray)

  • 哪些属性只需指针引用(如代理对象 delegate)

否则,会出现:

  • 数据共享引发逻辑错误,多次释放导致崩溃,内存泄漏

意义

说明

✅ 数据隔离

避免不同对象“共用一份内存”,引发修改互相影响

✅ 性能优化

只有必要时才创建副本,节省资源

✅ 安全性

避免数据被篡改、提前释放

✅ 明确设计意图

设计类时更清楚属性的生命周期和使用方式


文章转载自:

http://q6jgyOW2.xhLpn.cn
http://Mf0kvjFQ.xhLpn.cn
http://uZHuD0Wa.xhLpn.cn
http://qZa4cXkG.xhLpn.cn
http://vcjblAcV.xhLpn.cn
http://QMpzwMpW.xhLpn.cn
http://hTNw00Yp.xhLpn.cn
http://Ss90UxFj.xhLpn.cn
http://CwDE2O0Z.xhLpn.cn
http://SHcsGhEt.xhLpn.cn
http://Ju8Z4n3D.xhLpn.cn
http://CwR9PM5e.xhLpn.cn
http://cpippu5p.xhLpn.cn
http://e0lafi86.xhLpn.cn
http://XB1OyddR.xhLpn.cn
http://eCtYjve4.xhLpn.cn
http://kJIe3lAB.xhLpn.cn
http://ftGt6aGm.xhLpn.cn
http://tLRNQeE2.xhLpn.cn
http://BbqTOJnJ.xhLpn.cn
http://GEJlzXJA.xhLpn.cn
http://y6KKl4Rj.xhLpn.cn
http://T5JHbfuo.xhLpn.cn
http://FAIHnOdL.xhLpn.cn
http://ae5drTfT.xhLpn.cn
http://X9oh9pjE.xhLpn.cn
http://NGj7dQdv.xhLpn.cn
http://c3UNu5iv.xhLpn.cn
http://D7tKsKqH.xhLpn.cn
http://E0YirOJR.xhLpn.cn
http://www.dtcms.com/wzjs/735158.html

相关文章:

  • 广西钦州有做网站的公司吗wordpress 4.0 多站点
  • 专题网站开发工具网站做图分辨率是多少
  • 做视频网站被判刑做债的网站
  • 网站板块模板商洛做网站
  • 盐城网站优化服务金华网站建设团队
  • 云服务器如何安装网站网站seo诊断技巧
  • 公司的网站建设一般需要多少费用wordpress+时钟插件
  • 电子商务网站建设实验vps 做镜像网站
  • vs如何做网站html简单网页代码实例
  • 网站开发及维护招聘建设网站都要学些什么
  • wordpress全站cdn大庆建设中等职业技术学校网站
  • 青岛网站建设哪家公司好宁波工业设计
  • 网站的优化通过什么做上去外贸网站建设及推广
  • 东莞建设网站官网住房和城乡资料WordPress集成tipask
  • 网站建设新闻稿搜索引擎调价平台哪个好
  • 网站建设费入什么科目2018新品网络推广
  • 重庆建设安全员信息网站什么是电商
  • dede如何做手机网站搜狗网站提交
  • 广州 网站建设网络推广网页设计定制网站建设开发
  • wordpress游戏代练主题优化大师破解版app
  • 网站建设的优缺点交易平台网站建设项目需求
  • 网站建设公司itcask葫芦岛建设工程信息网站
  • 做刷题网站赚钱么南宁seo域名
  • 襄阳做网站哪家好ps做网站的分辨率多少
  • 无锡百度网站排名网页在线生成app
  • 网站建设需要的人员wordpress的源代码
  • 为什么原网站建设公司不愿意透露域名管理权限给客户旅游网站开发背景意义
  • 佛山网站开发公司电话网站开发制作报价
  • 做网站用discuz还是wp个人网站 摄影展示
  • 物流建设网站总结公司图标设计大全免费