iOS-Strong/Copy修饰词

在iOS中,string是用strong修饰还是用copy修饰?它们有什么区别呢?本文主要就来讨论这两个问题,在此之前,我们需要知道两个术语,浅拷贝和深拷贝

浅拷贝:指对内存地址的复制,让目标对象指针和源对象指向同一片内存空间,当内存销毁的时候,指向这片内存的指针需要赋值,要不然会成为野指针 深拷贝:指对对象具体内容复制,重新分配对象的内存地址,拷贝结束之后,两个对象虽然值是相同的,但是内存地址不一样,两个对象也互不影响,互不干涉

上代码,测试一下

NSString *str = @"test";
NSString *copyStr = [str copy];
NSMutableString *mutStr = [str mutableCopy];
    
NSLog(@"指针地址:str:%p--copyStr:%p--mutStr:%p",&str,&copyStr,&mutStr);
NSLog(@"内存地址:str:%p--copyStr:%p--mutStr:%p",str,copyStr,mutStr);

运行结果:

指针地址:str:0x16fb31678--copyStr:0x16fb31670--mutStr:0x16fb31668
内存地址:str:0x1002d4080--copyStr:0x1002d4080--mutStr:0x1c024af80

可以看出:copy实现了一次浅拷贝,mutableCopy实现了一次深拷贝 实际上,对于copy和mutableCopy我们可以得出下表的结论

理解了copy作用,我们就不难理解属性中的copy和strong了,实际上在属性中copy比strong多了一步,即在setter方法中

- (void)setName:(id)name{
    _name = [name copy];
}

举个例子:假设有这样一段代码

@property(copy)id obj;

self.obj = object;

此时obj是什么呢?有下面两种情况:
1. object是不可变对象,将会把object浅拷贝一次,赋值给obj
2. object是可变对象,将会把object深拷贝一次,赋值给obj
如果obj是用strong修饰的,就没有拷贝一说了,将会直接把object赋值给obj

在内存计数方面
strong 会使object引用计数+1,obj的引用计数为1
copy   如果object是不可变对象,object引用计数+1,obj的引用计数为1
       如果object是可变对象,会将object深拷贝一份,object的引用计数不会变,obj的引用计数为1

综上所述,我们可以得出以下结论

  1. 当属性本身是可变对象时 此时只能用strong修饰,因为如下图,下图中,name属性经过setter时,得到的永远是不可变对象,当调用可变方法时,就会崩溃
  1. 当属性的赋值来源是可变对象时,如下图,看日志输出,发现当使用strong时,来源发生改变,属性值会跟着发生改变,当实用copy时,来源发生改变,属性不会跟着变
  1. 当属性的赋值来源是不可变对象时,如下图,发现strong和copy并没有什么区别

所以我们在选用修饰词时,我们要根据,属性本身是否可变,对属性赋值的来源是否可变,属性是否需要跟随来源的变化而变化等情况来选用属性的修饰词,不过,在实际开发中,大多数情况都是用copy

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏微服务生态

Scala学习笔记(一)

lazy val forLater = someTimeConsumingOperation()

541
来自专栏coding for love

JS入门难点解析

(注1:如果有问题欢迎留言探讨,一起学习!转载请注明出处,喜欢可以点个赞哦!) (注2:更多内容请查看我的目录。)

562
来自专栏Java后端技术

这个坑,是时候填上了~

​  这两天,在网上逛的时候,发现了如下的一道面试题,感觉还有蛮有意思的,要是不仔细看还真容易掉到坑里面。第一眼看起来比较绕,所以比较难理解。最终我跳出了这个坑...

481
来自专栏步履前行

什么是面向对象

面向对象的特征有3个,封装、继承、多态。至于抽象的话,个人认为,应该是前面3大特征中都有抽象的思想,毕竟面向对象本身就是一种抽象。 比如 子类 extends ...

3376
来自专栏陈纪庚

javascript变量提升详解

对于大多数js开发者来说,变量提升可以说是一个非常常见的问题,但是可能很多人对其不是特别的了解。所以在此,我想来讲一讲。

782
来自专栏阿凯的Excel

Python读书笔记18(初识自定义函数)

在分享自定义函数之前,我们要弄明白什么是函数、方法。之前的教程我有刻意用方法和函数两种方式来称呼具体的内容。例如删除列表的某个元素! ? 方法是函数的一种,类中...

3489
来自专栏用户2442861的专栏

python 中迭代多个序列

http://blog.csdn.net/he_jian1/article/details/40819407

332
来自专栏编程

给初学者:JavaScript 中数组操作注意点

作者:CarterLi https://segmentfault.com/a/1190000012463583 不要用 for_in 遍历数组 这是 JavaS...

1736
来自专栏racaljk

[数据结构]C语言链表实现

我学数据结构的时候也是感觉很困难,当我学完后我发现了之所以困难时因为我没有系统的进行学习,而且很多教授都只是注重数据结构思想,而忽略了代码方面,为此我写了这些博...

583
来自专栏老马说编程

(18) 为什么说继承是把双刃剑 / 计算机程序的思维逻辑

继承是把双刃剑 通过前面几节,我们应该对继承有了一个比较好的理解,但之前我们说继承其实是把双刃剑,为什么这么说呢?一方面是因为继承是非常强大的,另一方面是因为...

2006

扫码关注云+社区