iOS中copy和strong修饰符的区别
iOS中copy和strong修饰符的区别
//用copys修饰的生成的都是不可变的对象 ,如果调用可变类型方法的直接报错
@property(nonatomic,copy)NSString * cpStr;
@property(nonatomic,strong)NSString *strongStr;
1.当copy的对象类型为不可变对象如NSString类型时,和Strong修饰作用是一样的
NSString *str = @"wxwx";
self.cpStr = str;
self.strongStr = str ;
str = @"haha";
NSLog(@"str==%p,\n cpstring==%p,\n storngstr==%p",str,_cpStr,_strongStr);
NSLog(@"str==%@,\n cpstring==%@,\n storngstr==%@",str,_cpStr,_strongStr);
//打印信息:
str==0x105086190,
cpstring==0x105086170,
storngstr==0x105086170
----------
str==haha,
cpstring==wxwx,
storngstr==wxwx
很明显两者指向的是同一块内存地址,由于指向不可变的对象不用担心对象值改变引起原始值的变化
2.再来看两者指向可变对象的时候
NSMutableString *str = [NSMutableString stringWithFormat:@"caca"];
self.cpStr = str;
self.strongStr = str ;
[str insertString:@"ha21" atIndex:];
NSLog(@"str==%p,\n cpstring==%p,\n storngstr==%p",str,_cpStr,_strongStr);
NSLog(@"str==%@,\n cpstring==%@,\n storngstr==%@",str,_cpStr,_strongStr);
可以看到打印信息为:
str==0x600002569aa0,
cpstring==0xf3479ef8a5126e6a,//指向的地址已经改变
storngstr==0x600002569aa0
----------------------
str==ha21caca,
cpstring==caca,//copy对象的值还是原始值。
storngstr==ha21caca
由于指向可变的对象,用copy修饰的话就算对象的值发生改变也不会影响本身
3.深拷贝,浅拷贝
浅拷贝:指向可变对象的时候利用copy,新产生一份内存,但子对象还是指向原先内存。
深拷贝:子对象也重新生成一份内存。
如下代码展示了浅拷贝:
NSMutableArray *arr1 =[ NSMutableArray arrayWithObjects:[NSMutableString stringWithString:@"tom"],[NSMutableString stringWithString:@"jack"], nil];
NSArray*arr2 = [arr1 copy];
[arr1[] appendString:@" new value"]; NSLog(@"浅拷贝---arr1==%@,arr2===%@ \n 地址---arr1=%p,arr2=%p",arr1,arr2,arr1,arr2);
查看log:
浅拷贝---arr1==(
"tom new value",
jack
),arr2===(
"tom new value",
jack
)
地址---arr1=0x1020309e0,arr2=0x102030de0
很明显,arr1,arr2的内存是不一致的,但里面的子对象指向的内存还是同一块.
深拷贝:实现深拷贝的方法,需要将子对象也都复制一份。比如通过遍历数组中的每个对象并未没个对象创建新的拷贝.
下面通过归档实现深拷贝:
NSMutableArray *agearr = [NSMutableArray arrayWithObjects:[NSMutableString stringWithString:@"jack"],[NSMutableString stringWithString:@"tom"], nil];
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:agearr];
NSMutableArray* agearr2 = [NSKeyedUnarchiver unarchiveObjectWithData:data];
NSMutableString *obj1 = agearr2[];
[obj1 appendString:@"----some value"]; NSMutableArray *tarr = [agearr mutableCopy];
[[tarr objectAtIndex:] appendString:@"==lepp"];
NSLog(@"age1===%@\n age2===%@ tarr==%@",agearr,agearr2,tarr);
查看Log:
age1===(
"jack==lepp",
tom
)
age2===(
"jack----some value",
tom
) tarr==(
"jack==lepp",
tom
)
总结:
当属性为不可变时用copy(防止属性值被篡改),指向可变属性时用strong(注:如果还是用copy,由于copy返回的都是不可变的对象,一旦调用不可变对象的方法就会引起崩溃,所以这里也不能用copy)
对于其他可变非可变类同理(NSArray,NSMutableArray等)
iOS中copy和strong修饰符的区别的更多相关文章
- IOS中 copy ,strong ,weak ,assign使用区别
.@property属性的用法 * weak(assign) : 代理\UI控件 * strong(retain) : 数组.模型)其他对象(除代理\UI控件\字符串以外的对象) * copy ...
- C#中override和new修饰符的区别
(new)“隐藏”,(override)“覆盖”(重写).不过要弄清楚这两个有什么区别确实也很难,因为子类在使用父类方法时根本看不出区别,子类不管父类是new了还是override了,用的都是父类方法 ...
- IOS开发 __weak与__block修饰符到底有什么区别
API Reference对__block变量修饰符有如下几处解释: //A powerful feature of blocks is that they can modify variables ...
- Java 中的 protected 访问修饰符你真的了解吗?
protected Java 中的 protected 访问修饰符 总结 在同一个包中,类中 protected 或 default 修饰的属性或方法可以在类外被其对象 (实例) 外部访问,也可以被子 ...
- 《挑战30天C++入门极限》入门教程:C++中的const限定修饰符
入门教程:C++中的const限定修饰符 const修饰符可以把对象转变成常数对象,什么意思呢? 意思就是说利用const进行修饰的变量的值在程序的任意位置将不能再被修改,就如同常数一样使用! ...
- Java语言中的访问权限修饰符
一个Java应用有很多类,但是有些类,并不希望被其他类使用.每个类中都有数据成员和方法成员,但是并不是每个数据和方法,都允许在其他类中调用.如何能做到访问控制呢?就需要使用访问权限修饰符. Java语 ...
- __block和__weak修饰符的区别
block下循环引用的问题 __block本身并不能避免循环引用,避免循环引用需要在block内部把__block修饰的obj置为nil __weak可以避免循环引用,但是其会导致外部对象释放了之后, ...
- Nullable<T>、Nullable、null、?修饰符的区别
这章我们讨论一下Nullable<T>.Nullable.null.?修饰符的区别 原创文章 Nullable<T>的前世今生 讨论它们之前,我们有必要讨论一下Nullable ...
- Objective C中的ARC的修饰符的使用---- 学习笔记九
#import <Foundation/Foundation.h> @interface Test : NSObject /** * 默认的就是__strong,这里只是做示范,实际使用时 ...
随机推荐
- 006-nginx.conf详解-error_page 使用
一.概述 nginx指令error_page的作用是当发生错误的时候能够显示一个预定义的uri 1.1.使用步骤 更改nginx.conf在http定义区域加入: proxy_intercept_er ...
- matlab学习笔记13_3创建函数句柄
一起来学matlab-matlab学习笔记13函数 13_3 创建函数句柄 觉得有用的话,欢迎一起讨论相互学习~Follow Me 参考文献 https://ww2.mathworks.cn/help ...
- word中的总页数不包括封面、目录
删除分隔符:选项-显示-显示所有格式标记
- 微信小程序框架 同时兼容QQ小程序
最近一直在开发微信小程序,经过几个版本的迭代开发,代码终于能够达到框架级别,动态配置.除了界面有些寒酸以外,功能上还是挺完备的. 主要有以下特点 1.整个程序所需url地址均在api.js中定义,环境 ...
- vue-cli3项目关闭烦人的代码检测
参考博客:https://blog.csdn.net/e1172090224/article/details/99636767 vue.config.js module.exports = { lin ...
- 5中I/O模型
输入操作包括两个阶段1.等待网络数据到达,被复制到内核中的缓冲区2.从内核缓冲区复制到进程缓冲区5种I/O模型1.阻塞式I/O:包含数据被复制到内核缓冲区和应用进程缓冲区两个过程,调用recvfrom ...
- shell中 >/dev/null 2>&1是什么意思
原文地址:http://juke.outofmemory.cn/entry/295292 我们经常能在 shell 脚本中发现 >/dev/null 2>&1 这样的语句.以前的我 ...
- ANR无法生成traces.txt文件
在有些设备上ANR无法生成traces.txt文件,kill -3又不能准确把握时机或者没权限,可能是软件访问这个路径失败,可以在/data/anr/下面建立一个空的traces.txt,注意保证an ...
- SQL Server表分区(转)
什么是表分区 一般情况下,我们建立数据库表时,表数据都存放在一个文件里. 但是如果是分区表的话,表数据就会按照你指定的规则分放到不同的文件里,把一个大的数据文件拆分为多个小文件,还可以把这些小文件放在 ...
- 【CUDA开发-并行计算】NVIDIA深度学习应用之五大杀器
来自吉浦迅科技 整理发布 http://mp.weixin.qq.com/s?__biz=MjM5NTE3Nzk4MQ==&mid=2651231163&idx=1&sn=d4 ...