前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >iOS内存管理(三)-深拷贝和浅拷贝

iOS内存管理(三)-深拷贝和浅拷贝

原创
作者头像
用户6658895
修改2023-07-21 11:31:15
3130
修改2023-07-21 11:31:15
举报

概念

  • 浅拷贝:浅拷贝就是指针拷贝,就是拷贝一份指向该对象的指针,就是复制的对象和原对象都指向同一个地址
  • 深拷贝:深拷贝是内容拷贝,真正的复制一份,复制对象的内容。复制的对象指向新的地址。

copy 和 mutablecopy

  • mutableCopy拷贝出来的对象类型总是可变类型(例如, NSMutableString, NSMutableDictionary, NSMutableArray等等)
  • mutableCopy拷贝出来的对象类型总是可变类型(例如, NSMutableString, NSMutableDictionary, NSMutableArray等等)
  • 对象要想具有copy和mutablecopy功能要是NSCopying和NSMutableCopy协议,实现copywithzone和mutablecopywithzone

NSString为什么用copy修饰,不用strong

代码语言:objective-c
复制
#import "ViewController.h"
@interface ViewController ()
@property (nonatomic, strong) NSString *strongString;
@property (nonatomic, copy) NSString *copyedString;
@end

@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    [self demo2];
    // 對於不可變字符串而言,使用strong和copy都是淺拷貝,打印的地址都是一致的
    NSString *string = [NSString stringWithFormat:@"123"];
    self.strongString = string;
    self.copyedString = string;
    NSLog(@" string: %p",string);
    NSLog(@" strongString : %p",self.strongString);
    NSLog(@" copyedString : %p",self.copyedString);

}
    
// 測試可變字符串使用copy屬性(其實使用copy屬性 至關於該變量進行了一次copy操做[string copy])
- (void)demo2{

    // 不可變字符串
    NSMutableString *string = [NSMutableString stringWithFormat:@"123"];
    // 用strong修飾的屬性記錄
    self.strongString = string;
    // 用copy修飾的屬性記錄
    self.copyedString = string;
    // 打印地址
    NSLog(@" string: %p",string);
    NSLog(@" strongString : %p",self.strongString);
    NSLog(@" copyedString : %p",self.copyedString);
    NSLog(@"%@",self.copyedString);
    // 改變字符串,對比用strong和copy修飾的屬性的區別
    [string appendString:@"bbb"];
    NSLog(@" strongString : %@  %p",self.strongString, self.strongString);
    NSLog(@" copyedString : %@  %p",self.copyedString, self.copyedString);

}
@end

咱們發現用copy修飾的屬性地址已經變了,緣由是NSMutableString的對象copy操做 產生新地址,產生的是不可變的對象,因此改變string,,不會改變被copy修飾的屬性.正好符合咱們改變string 不會改變self.copyedstring的值,而self.strongstring的值已經改變了

iOS block 为啥官方文档建议用 copy 修饰

block 本质上是一个OC对象,内部有个 isa 指针,可以用 retain/strong/copy 等修饰词修饰。但是 block 在创建的时候内存默认分配在栈上,而不是堆上的。所以它的作用域仅限创建时候的作用域内,当你在该作用域外调用该 block 时,程序就会崩溃。

NSString的内存

三种不同类型的 string
  • __NSCFConstantString
  • NSTaggedPointerString
  • __NSCFString
生成一个NSString类型的字符串有三种方法:

方法1.直接赋值: NSString *testStr1 = @"a";

方法2.类函数初始化生成: (自动释放内存)

代码语言:javascript
复制
 NSString *testStr2 = [NSString stringWithString:@"b"];
 NSString *testStr3 = [NSString stringWithFormat:@"c"];

方法3.实例方法初始化生成: (手动释放内存,存在isa优化,个数小于9,不存在中文和特殊字符,为tagged类型)

代码语言:javascript
复制
 NSString *testStr4 = [[NSString alloc] initWithString:@"d"];
 NSString *testStr5 = [[NSString alloc] initWithFormat:@"e"];

总结

  • 对于不可变对象(不可变对象和不可变集合对象),进行copy都是指针拷贝,进行mutablecopy都是内容拷贝。
  • 对于可变对象(可变对象和可变集合对象),进行copy和mutablecopy都是内容copy。
  • 不管是可变对象和不可变对象进行copy操作,产生的都是不可变的对象,进行mutablecopy操作产生的都是可变的对象。
  • 对任何一个对象进行深拷贝,都是单层深拷贝。例如:对NSArray进行深拷贝,但是数组里面的元素还是指针拷贝。就是两个数组的地址不一样,但是里面的元素地址是一样的。所以要想让数组中的元素也是不一样的地址,那就对每个元素进行深拷贝。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 概念
  • copy 和 mutablecopy
  • NSString为什么用copy修饰,不用strong
  • iOS block 为啥官方文档建议用 copy 修饰
  • NSString的内存
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档