iOS 关键词assign、strong、copy、weak、unsafe_unretained
关键词assign、strong、copy、weak、unsafe_unretained
影响:
- 是否开辟新的内存
- 是否有引用计数增加
strong
指向并拥有该对象。其修饰的对象引用计数会 +1,该对象只要引用计数不为 0 就不会销毁,置为 nil 可以销毁它。
一般用于修饰对象类型、字符串、集合类的可变版本NSMutable
。
// .h 文件
@property (nonatomic, strong) NSMutableArray * nArr;
// .m 文件
{
NSMutableArray * mArr = [[NSMutableArray alloc]
initWithObjects:@"a", @"b", @"c", nil];
self.nArr = mArr; // setter方法赋值时, 指针拷贝(浅拷贝)
[mArr addObject:@"d"];
NSLog(@"%@ %p %p", self.nArr, self.nArr, mArr);
}
//打印结果
2018-10-16 19:29:27.550029+0800 Demo[64192:936916] (
a,
b,
c,
d
) 0x60000005bc60 0x60000005bc60 // 地址相同
copy
调用该变量的setter
进行赋值,会把对象(值)拷贝一份副本,再赋。两个指针指向不同的内存地址,持有两个不同的对象。另一个对象发生变化不影响本身。
一般NSString、NSArray、NSDictionary
等 用 copy 修饰,因为有可能赋值一个可变类型的指针,此时能保证属性值不会受外界影响。
// .h 文件
@property (nonatomic, copy) NSArray * nArr;
// .m 文件
{
NSMutableArray * mArr = [[NSMutableArray alloc]
initWithObjects:@"a", @"b", @"c", nil];
self.nArr = mArr; // setter方法赋值时, 内容拷贝(深拷贝)
[mArr addObject:@"d"];
NSLog(@"%@ %p %p", self.nArr, self.nArr, mArr);
}
2018-10-16 19:27:27.678093+0800 Demo[63966:933713] (
a,
b,
c
) 0x60000024e070 0x60000024c960 // 地址不同
自定义对象需要实现NSCoping
协议:
- (instancetype)copyWithZone:(NSZone *)zone
{
AModel * model = [[[self class] allocWithZone:zone] init];
model.title = self.title;
model.desc = self.desc;
return model;
}
对比:strong 、copy
strong 的赋值是多个指针指向同一个地址,
copy 的赋值是每次会在内存中赋值一份对象,指针指向不同的地址。
- 在MRC下,block属性为什么要用copy来修饰?
因为block在创建时,它的内存是分配在栈(stack)上的,而不是在堆(heap)上,栈内存可能被随时回收。本身的作于域属于创建时的作用域,一旦在创建时候的作用域外调用block,将导致程序崩溃。通过copy可以把block拷贝到堆,保证block的声明域外使用。在ARC下写不写都行,编译器会自动对block进行copy操作。
assign
主要用于修饰 基本数据类型 等非OC对象,如 NSInteger
、CGFloat
等。
这些数值主要存在于栈
中。
可以用来修饰对象。但是!被
assign
修饰的对象在释放后,指针的地址没被置为nil,成为野指针
。如果后续在分配对象到堆上的某块内存时,正好分到这块地址,程序就会crash。
不管是 MRC 还是 ARC,使用 assign 时,都需要注意释放。
weak
指向 但不拥有该对象。其修饰的对象引用计数不会增加,属性所指的对象遭到摧毁时,值会清空。
ARC 环境下一般用于修饰可能会引起循环引用的对象。
delegate、xib 控件用 weak 修饰。
在使用 delegate 时,需要注意:
- MRC 下,使用 assign。
- ARC 下,都建议使用 weak,防止出现循环引用。否则如果用assign,当页面销毁时,很可能出现 delegate 对象无效,导致程序 crash。
unsafe_unretained
与 weak 类型相似,但是销毁时不自动清空,容易形成野指针。
对比:
weak
引用的 OC 对象被销毁时,指针会被自动清空,不再指向销毁的对象,不会产生野指针错误;assign
修饰基本数据类型,内存在栈上由系统自动回收。修饰对象类型时,也可能存在野指针。
@property、@dynamic 和 @synthesize
@property
@property = ivr + getter + setter
编译器自动编写访问这些属性所需的方法。
@dynamic
告诉编译器不要自动创建实现属性所用的实例变量,也不要为其创建存取方法。即使编译器发现没有定义存取方法也不会报错,运行期会导致崩溃。
@synthesize
在类的实现文件里, 指定实例变量的名称。
iOS 关键词assign、strong、copy、weak、unsafe_unretained的更多相关文章
- iOS retain、strong、weak、assign
iOS retain.strong.weak.assign strong与weak是由ARC新引入的对象变量属性xcode 4.2(ios sdk4.3和以下版本)和之前的版本使用的是retain和a ...
- iOS中assign、copy 、retain等关键字的含义
iOS中assign.copy .retain等关键字的含义 转自:http://my.oschina.net/majiage/blog/267409 assign: 简单赋值,不更改索引计数cop ...
- iOS - property,strong,weak,retain,assign,copy,nomatic 的区别及使用
1:ARC环境下,strong代替retain.weak代替assign,xcode 4.2(ios sdk4.3和以下版本)和之前的版本使用的是retain和assign,是不支持ARC的.xcod ...
- iOS中assign,copy,retain之间的区别以及weak和strong的区别
@property (nonatomic, assign) NSString *title; 什么是assign,copy,retain之间的区别? assign: 简单赋值,不更改索引计数(Refe ...
- assign, retain, copy, weak, strong
一.assign, retain, copy 的区别(引用计数 RC reference count) 参考:IOS基础:retain,copy,assign及autorelease 1. 假设你用m ...
- iOS中assign,copy,retain之间的区别以及weak和strong的区别(面试)
• copy: 用于希望保持一份传入值的拷贝,而不是值自身的情况,即把原来的对象完整的赋值到另外一地方,重新加载一内存区,一个地方变了不影响另一个地方的对象. • assign: 简单的直接赋值,相 ...
- 对于atomic nonatomic assign retain copy strong weak的简单理解
atomic和nonatomic用来决定编译器生成的getter和setter是否为原子操作 1)atomic 设置成员变量的@property属性时,atomic是默认值,提供多线程安全 在多线程环 ...
- iOS property中的strong 、weak、copy 、assign 、retain 、unsafe_unretained 与autoreleasing区别和作用详解
iOS5中加入了新知识,就是ARC,其实我并不是很喜欢它,因为习惯了自己管理内存.但是学习还是很有必要的. 在iOS开发过程中,属性的定义往往与retain, assign, copy有关,我想大家都 ...
- property中的strong 、weak、copy 、assign 、retain 、unsafe_unretained 与autoreleasing区别和作用详解
iOS5中加入了新知识,就是ARC,其实我并不是很喜欢它,因为习惯了自己管理内存.但是学习还是很有必要的. 在iOS开发过程中,属性的定义往往与retain, assign, copy有关,我想大家都 ...
随机推荐
- [转]Windows内存堆内容整理总结
在系统安全研究中,堆,是一个极其重要的内存区域以及研究的热点.堆,区别于栈区.全局数据区以及代码区,它的主要作用是允许程序在运行时动态地申请某个大小的内存空间.本文将从宏观到微观,简单梳理总结一下Wi ...
- osg::Node位置移动
osg::Node节点移动的时候,可以使用osg::Matrix::translate 来完成 osg::Matrix::translate中的参数是 当前位置到目标位置需要改变的值,所以,传递参 ...
- Qt开发经验小技巧11-20
获取类的属性 const QMetaObject *metaobject = object->metaObject(); int count = metaobject->propertyC ...
- Linux下使用iptables配置防火墙端口转发
1.背景 一些情况下,在linux上面我们想使用80-1024之间的端口,这个时候需要root权限. 当时root权限容易被提权,特别是早起那些Struct2,漏洞爆出的时候,一抓一个准-root权限 ...
- 如何优化代码和RAM大小
如果供应商为我自己的项目提供了一个起点,那就太好了.工作'眨眼'始终是一个伟大的首发.方便总是有代价,而且“眨眼”就是夸大“切换GPIO引脚”的代码大小.对于具有少量RAM和FLASH的设备,这可能会 ...
- Java之安装JDK
因为Java程序必须运行在JVM只是,所以我们第一件事情就是安装JDK 从Oracle官网下载最新稳定版JDK 一,Linux系统CentOS安装JDK 下载rpm安装包 安装 rpm -ivh jd ...
- oracle11G 命令【导库数量对比】
1.查询用户有哪些表 select * from all_tables where owner='ZJY'; 160 rows selected. 2. 查询总数 select object_type ...
- 高级UI-画笔Paint
在UI这一块,谈到自定义,就离不开画笔和画布的使用话题,在自定义控件的时候,为了做出炫酷的效果,我们往往会使用画笔和画布,那么这里我们就先来看看画笔的使用吧 简单使用例子 自定义一个View publ ...
- KMP操作大全与kuangbin kmp套题题解
先搬运,比赛后整理 https://blog.csdn.net/vaeloverforever/article/details/82024957
- [转帖]Socat 入门教程
https://www.hi-linux.com/posts/61543.html 现在安装k8s 必须带 socat 今天看一下socat 到底是啥东西呢. Socat 是 Linux 下的一个多功 ...