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

公司做网站要多长时间审核杭州网站建设

公司做网站要多长时间审核,杭州网站建设,上海建设银行黄浦区营业网站,自己可以做网站么对象复制与拷贝 文章目录 对象复制与拷贝copy与mutablecopycopy与mutablecopy的简介示例:不可变对象的复制可变对象的复制 NSCopying和NSMutableCopying协议深复刻和浅复刻浅拷贝(Shallow Copy):深拷贝(Deep Copy&…

对象复制与拷贝

文章目录

  • 对象复制与拷贝
    • copy与mutablecopy
      • copy与mutablecopy的简介
      • 示例:
        • 不可变对象的复制
        • 可变对象的复制
    • NSCopying和NSMutableCopying协议
    • 深复刻和浅复刻
      • 浅拷贝(Shallow Copy):
      • 深拷贝(Deep Copy):
    • setter方法的复制选项

copy与mutablecopy

copy与mutablecopy的简介

copymutablecopy都是NSObeject所提供用来复制对象的方法,但它们有着不同的行为,主要区别如下:

  1. copy 方法:
  • copy 方法用于创建一个不可变的副本,无论原始对象是可变的还是不可变的。
  • 对于不可变对象,copy 方法仅仅是增加了引用计数,返回的仍然是原始对象本身。
  • 对于可变对象,copy 方法会创建一个新的不可变对象,内容与原始对象相同。

mutableCopy 方法:

  • mutableCopy 方法用于创建一个可变的副本,无论原始对象是可变的还是不可变的。
  • 对于不可变对象,mutableCopy 方法会创建一个新的可变对象,内容与原始对象相同。
  • 对于可变对象,mutableCopy 方法会创建一个新的可变对象,内容与原始对象相同。

总结一下,主要区别在于:

  • copy 返回的是不可变副本,而 mutableCopy 返回的是可变副本。
  • copy 对不可变对象和可变对象的行为不同,而 mutableCopy 则对所有对象的行为都一致。

示例:

不可变对象的复制
#import <Foundation/Foundation.h>int main(int argc, const char * argv[]) {@autoreleasepool {NSString* str1 = @"deer";NSString* str2 = str1;NSString* strcopy = [str1 copy];NSString* strmutablecopy = [str1 mutableCopy];NSLog(@"%p",str1);NSLog(@"%p",str2);NSLog(@"%p",strcopy);NSLog(@"%p",strmutablecopy);}return 0;
}

image-20240507192642271

不难看出来,str1,str2, strcopy ,指向的都为同一内存区域,为浅拷贝,由于mutablecopy生成了新的NSMutableString所以系统为其重新开辟一块空间,进行了深拷贝。

可变对象的复制
#import <Foundation/Foundation.h>int main(int argc, const char * argv[]) {@autoreleasepool {NSMutableString *mstr = [NSMutableString stringWithString:@"hello"];NSString *mstrcopy1 = [mstr copy];NSMutableString *mstrcopy2 = [mstr copy];NSMutableString *mstrmutablecopy = [mstr mutableCopy];[mstr appendString:@",aa"];//[mstrcopy2 appendString:@",bb"];[mstrmutablecopy appendString:@",cc"];NSLog(@"%p",mstr);NSLog(@"%p",mstrcopy1);NSLog(@"%p",mstrcopy2);NSLog(@"%p",mstrmutablecopy);}return 0;
}

对于注释的那一句代码,由于mstrcopy是通过copy方法得来,类型为NSString是不可变的,所以后面无法进行追加。可以发现通过copy得到的字符串指向的是同一片地址,但是复制得到的地址相对于原来的mstr都是不同的,所以我们可以知道对于可变对象进行copymutablecopy都是进行深拷贝。

NSCopying和NSMutableCopying协议

虽然NSObject虽然都给出了copymutablecopy的方法,但是不一定在任何时候都能够使用,为了确保一个对象可以调用copy方法复制得到自身的不可变副本,我们需要做如下事情

  • 让该类实现NSCopying协议
  • 让该类实现copyWithZone方法

对于mutablecopy也是同理

  • 实现NSMutableCopying协议
  • 让该类实现mutableCopyWithZone方法
#import <Foundation/Foundation.h>@interface MyObject : NSObject <NSCopying>@property (nonatomic, strong) NSMutableString *name;
@property (nonatomic, assign) int age;@end@implementation MyObject- (id)copyWithZone:(NSZone *)zone {MyObject *copy = [[[self class] allocWithZone:zone] init];// 递归复制子对象copy.name = self.name;copy.age = self.age;return copy;
}-(NSString*)description {return [NSString stringWithFormat:@"name = %@, age = %d", self.name, self.age];
}
@endint main(int argc, const char * argv[]) {@autoreleasepool {// 创建原始对象MyObject *org = [MyObject new];org.name = [NSMutableString stringWithString:@"aa"];org.age = 10;NSLog(@"%@",org);MyObject *copy1 = [org copy];NSLog(@"%@",copy1);copy1.name = [NSMutableString stringWithString:@"bb"];copy1.age = 20;NSLog(@"%@",org);NSLog(@"%@",copy1);}return 0;
}

从以上程序我们看出来,我们对org进行一次副本复制,对得到的copy的成员变量进行赋值,对org不会产生影响。

image-20240507221647973

#import <Foundation/Foundation.h>@interface MyObject : NSObject <NSCopying>@property (nonatomic, strong) NSMutableString *name;
@property (nonatomic, assign) int age;@end@implementation MyObject- (id)copyWithZone:(NSZone *)zone {MyObject *copy = [[[self class] allocWithZone:zone] init];// 递归复制子对象copy.name = self.name;copy.age = self.age;return copy;
}-(NSString*)description {return [NSString stringWithFormat:@"name = %@, age = %d", self.name, self.age];
}
@endint main(int argc, const char * argv[]) {@autoreleasepool {// 创建原始对象MyObject *org = [MyObject new];org.name = [NSMutableString stringWithString:@"aa"];org.age = 10;NSLog(@"%@",org);MyObject *copy1 = [org copy];NSLog(@"%@",copy1);}return 0;
}

深复刻和浅复刻

深拷贝(Deep Copy)和浅拷贝(Shallow Copy)是在编程中经常遇到的两个概念,它们描述了在复制对象时复制的内容的不同程度。

浅拷贝(Shallow Copy):

浅拷贝是指将一个对象复制到一个新的对象中,即将对内存指针的复制,并增加其引用计数。如果对象包含其他对象的引用,浅拷贝将不会复制这些引用的对象,而是将其引用复制到新对象中。因此,新对象和原对象中的引用指向相同的对象。如果其中一个对象修改了共享对象,另一个对象也会受到影响。当使用A指针改变内容时,B指针指向的内容也会跟着改变

image-20240507191217818

深拷贝(Deep Copy):

深拷贝是指将一个对象递归复制到一个新的对象中,开辟一片新的空间,并且复制所有引用的对象,直至没有任何共用的部分。这意味着,新对象中的每个对象都是原始对象的副本,而不是共享的。因此,如果其中一个对象修改了它指针所指向的对象,另一个对象不会受到影响。

image-20240507191437571

对于上图来说,分配了新的内存,改变A指针指向的值,不会影响到指针B指向值的内容。

通常情况下,浅拷贝的效率比深拷贝高,因为它不需要递归地复制所有引用的对象。但是,在需要保持对象之间的独立性时,深拷贝是必需的。

我们再来探究一下我们刚刚看到的例子,

#import <Foundation/Foundation.h>@interface MyObject : NSObject <NSCopying>@property (nonatomic, strong) NSMutableString *name;
@property (nonatomic, assign) int age;@end@implementation MyObject- (id)copyWithZone:(NSZone *)zone {MyObject *copy = [[[self class] allocWithZone:zone] init];// 递归复制子对象copy.name = self.name;copy.age = self.age;return copy;
}-(NSString*)description {return [NSString stringWithFormat:@"name = %@, age = %d", self.name, self.age];
}
@endint main(int argc, const char * argv[]) {@autoreleasepool {// 创建原始对象MyObject *org = [MyObject new];org.name = [NSMutableString stringWithString:@"aa"];org.age = 10;NSLog(@"%@",org);MyObject *copy1 = [org copy];NSLog(@"%@",copy1);[copy1.name replaceCharactersInRange:NSMakeRange(0,2) withString:@"bb"];copy1.age = 20;NSLog(@"%@",copy1);NSLog(@"%@",org);}return 0;
}

我们的程序输出以下结果。

似乎很奇怪,我们通过repalce的函数去修改字符串,使得orgcopy的字符串内容都发生了改变,想要解决这个问题我们可以画一个图来辅助我们进行理解。

image-20240508200450863

对于即将被复制的org来说,变量name之中存储的是字符串的地址指针,而不是字符串本身,如果进行copy.name = self.name; copy.age = self.age;,那么只是将字符串的地址赋给copy之中的name属性,实际上两者指针都指向一个相同的NSMutableString类型字符串。

image-20240508201004905

对于这种复制模式我们就称之为浅复制,在内存中复制一个对象,但是原来的和复制得到的内容指向一个相同的对象,也就是说两个对象都存在依然存在的部分

那如果要实现深复制呢?前面说过深复制不仅会对对象本身进行复制,而且还会"递归"复制每一个指针的属性,直到两者没有共同的部分。我们将copyWithZone的代码进行一些修改就能实现深复制的原理。

- (id)copyWithZone:(NSZone *)zone {MyObject *copy = [[[self class] allocWithZone:zone] init];// 递归复制子对象copy.name = [self.name mutableCopy];copy.age = self.age;return copy;
}

我们将原对象的属性值复制了一份可变的副本,再将新的可变副本的内容赋值给新对象的name属性,与原先的对象再无共用的部分,实现了深复制

一般来说,实现深复制的难度很大,对于包含大量指针属性的对象来说,更或者对象中的变量中又嵌套了一层指针的话,那会更加复杂

setter方法的复制选项

当属性声明为 copy 时,在 setter 方法中会执行深复制操作。这意味着在设置属性值时,会创建一个属性值的副本,而不是直接引用传入的对象。

考虑以下代码:

@property (nonatomic, copy) NSString *name;

对应的 setter 方法会类似于这样:

- (void)setName:(NSString *)name {if (_name != name) {_name = [name copy];}
}

在这个 setter 方法中,首先进行了对象的比较,确保新值和旧值不是同一个对象。然后,使用 copy 方法来创建新值的副本,并将副本赋值给属性 _name。这样做可以确保属性值的安全性,防止外部对象对属性值的意外修改。

copy 操作实际上是执行了浅复制,它只会复制对象的指针,而不会复制对象本身。这意味着它会创建一个新的指针,指向相同的内存地址,而不是创建一个完全独立的副本。

对于不可变对象,由于其内容是不可变的,因此可以安全地使用 copy 属性。对于可变对象而言,使用copy可能会导致意外的行为。因为修改一个对象会影响到所有指向该对象的指针。这就是为什么使用 copy 属性时需要小心,特别是。另外,如果属性值是可变对象,那么每次设置属性值时都会创建一个新的不可变副本,这样会导致性能开销增加。

需要注意的是,copy 属性通常适用于容器类对象和其他可复制的对象,但对于自定义类对象,需要确保其实现了 NSCopying 协议。否则,编译器会报错。

http://www.jinmujx.cn/news/110527.html

相关文章:

  • 屏山县建设招标网站新闻源发稿平台
  • 日用品企业网站建设全网营销推广案例
  • 网站建设项目实施方案百度一下你就知道移动首页
  • 女士服装定制网站怎么创建网站免费建立个人网站
  • 青岛做网站哪家优化好网络舆情监测
  • 做自媒体那几个网站好点百度的广告推广需要多少费用
  • 建设网站收集加工素材教案直通车官网
  • 建设人才信息网是什么网站优化网站打开速度
  • com后缀的网站厦门seo外包平台
  • 品牌微信网站开发电影站的seo
  • 响应式网站制作视频营销推广投放
  • html5自适应网站模版出售友情链接是什么意思
  • 扬州建设投资集团网站重庆网站搜索引擎seo
  • wordpress恶意验证码产品seo基础优化
  • 怎么做网站赚钱吗营销网络的建设怎么写
  • 做旅行攻略的网站自己怎么优化网站
  • 系统优化的方法政治sem和seo
  • 呼和浩特市网站建设178软文网
  • 苏州营销型网站seo研究中心vip教程
  • 南开网站建设关键词搜索指数
  • 江西奶茶加盟网站建设seo网站排名全选
  • post wordpress api灰色词seo排名
  • 安徽安庆网站建设公司线上培训机构
  • 纯 flash 网站湘潭营销型网站建设
  • 北京管理咨询公司aso优化教程
  • 音乐网站怎么建设外包公司的优势和劣势
  • 如何制作独立网站如何用模板做网站
  • 编译django做的网站汕头seo排名收费
  • 做的好微信商城网站吗百度app客服人工电话
  • 设计需求网站网站seo诊断分析