当前位置:网站首页>[OC学习笔记]属性关键字
[OC学习笔记]属性关键字
2022-07-30 17:32:00 【Billy Miracle】
@property
@property关键字可以自动生成某个成员变量的setter和getter的声明。@synthesize关键字会指定一个以下划线 ( _ ) 为前缀,再加上属性名(例如_<name>)的成员变量。 并且由编译器自动进行该属性setter和getter的实现。@dynamic关键字,编译器就不会自动合成存取方法,一般用在给category添加属性的时候。
注意,分类不能添加成员变量,但是可以添加属性,从底层原理来说:分类是在运行时去把分类中的方法添加到类的方法列表里,类的底层其实是结构体,分类可以添加属性,不能添加成员变量,因为结构体声明后不能加成员,而属性是结构体里的一个列表(rw:property_array_t / ro: property_list_t),就是可以加的。
正确的做法是我们通过手动的实现setter/getter,通过关联对象绑定属性值到分类上。
默认设置
- 基本数据类型:
atomic,readwrite,assign - 对象类型:
atomic,readwrite,strong
属性关键字
| 分类 | 属性关键字 |
|---|---|
| 原子性 | atomic、nonatomic |
| 读写权限 | readwrite、readonly、setter、getter |
| 内存管理 | assign、weak、unsafe_unretained、retain、strong、copy |
| 可空性 | (nullable、_Nullable 、__nullable)、(nonnull、_Nonnull、__nonnull)、(null_unspecified、_Null_unspecified 、__null_unspecified)、null_resettable |
原子性
| 属性关键字 | 用法 |
|---|---|
| atomic | 原子性(默认),编译器会自动生成互斥锁,对 setter 和 getter 方法进行加锁,可以保证属性的赋值和取值的原子性操作是线程安全的,但不包括操作和访问。比如说 atomic 修饰的是一个数组的话,那么我们对数组进行赋值和取值是可以保证线程安全的。但是如果我们对数组进行操作,比如说给数组添加对象或者移除对象,是不在 atomic 的负责范围之内的,所以给被 atomic 修饰的数组添加对象或者移除对象是没办法保证线程安全的。 |
| nonatomic | 非原子性,一般属性都用 nonatomic 进行修饰,因为 atomic 非常耗时。 |
读写权限
| 属性关键字 | 用法 |
|---|---|
| readwrite | 可读可写(默认),同时生成 setter 方法和 getter 方法的声明和实现。 |
| readonly | 只读,只生成 getter 方法的声明和实现。 |
| setter | 可以指定生成的 setter 方法名,如 setter = setName。 |
| getter | 可以指定生成的 getter 方法名,如 getter = getName。 |
内存管理
| 属性关键字 | 用法 |
|---|---|
| assign | 1. 既可以修饰基本数据类型,也可以修饰对象类型; 2. setter 方法的实现是直接赋值,一般用于基本数据类型 ; 3. 修饰基本数据类型,如 NSInteger、BOOL、int、float 等; 4. 修饰对象类型时,不增加其引用计数; 5. 会产生悬垂指针(悬垂指针:assign 修饰的对象在被释放之后,指针仍然指向原对象地址,该指针变为悬垂指针。这时候如果继续通过该指针访问原对象的话,就可能导致程序崩溃)。 |
| weak | 1. 只能修饰对象类型; 2. ARC 下才能使用; 3. 修饰弱引用,不增加对象引用计数,主要可以用于避免循环引用; 4. weak 修饰的对象在被释放之后,会自动将指针置为 nil,不会产生悬垂指针。 |
| unsafe_unretained | 1. 既可以修饰基本数据类型,也可以修饰对象类型; 2. MRC 下经常使用,ARC 下基本不用; 3. 同 weak,区别就在于 unsafe_unretained 会产生悬垂指针。 |
| retain | 1. MRC 下使用,ARC 下基本使用 strong; 2. 修饰强引用,将指针原来指向的旧对象释放掉,然后指向新对象,同时将新对象的引用计数加1;3. setter 方法的实现是 release 旧值,retain 新值,用于OC对象类型。 |
| strong | 1. ARC 下才能使用; 2. 原理同 retain; 3. 但是在修饰 block 时,strong 相当于 copy,而 retain 相当于 assign。 |
| copy | setter 方法的实现是 release 旧值,copy 新值,用于 NSString、block 等类型。 |
所有权修饰符
| 所有权修饰符 | 用法 |
|---|---|
| __strong | 1. 强引用持有对象,可以对应 strong、retain、copy 关键字。 2. 编译器将为 strong、retain、copy 修饰的属性生成带 __strong 所有权修饰符的实例变量。 |
| __weak | 1. 弱引用持有对象,对应 weak 关键字,ARC下用来防止循环引用。 2. 编译器将为 weak 修饰的属性生成带 __weak 所有权修饰符的实例变量。 |
| __unsafe_unretained | 1. 弱引用持有对象,对应 unsafe_unretained、assign 关键字,MRC下用来防止循环引用。 2. 编译器将为 unsafe_unretained 修饰的属性生成带 __unsafe_unretained 所有权修饰符的实例变量。 3. 与 __weak 相比,它不需要遍历 weak 表来检查对象是否 nil,性能上要更好一些。但是它会产生悬垂指针。 |
| __autoreleasing | 在 MRC 中我们可以给对象发送 autorelease 消息来将它注册到 autoreleasepool 中,而在 ARC 中我们可以使用 __autoreleasing 修饰符修饰对象将对象注册到 autoreleasepool 中。 |
一些问题
Q:atomic 修饰的属性是怎么样保存线程安全的?
答: 编译器会自动生成互斥锁,对
setter和getter方法进行加锁,可以保证属性的赋值和取值原子性操作是线程安全的,但不包括操作和访问。比如说atomic修饰的是一个数组的话,那么我们对数组进行赋值和取值是可以保证线程安全的。但是如果我们对数组进行操作,比如说给数组添加对象或者移除对象,是不在atomic的负责范围之内的,所以给被atomic修饰的数组添加对象或者移除对象是没办法保证线程安全的。
Q:什么时候使用 weak/__weak 关键字?
答:ARC 中为了避免循环引用而使用,可以让相互引用的对象中的一个使用
weak/__weak弱引用修饰,常用于对delegate和block的修饰;
Q:assign 和 weak 关键字的区别有哪些?
weak只能修饰对象,而assign既可以修饰对象也可以修饰基本数据类型;assign修饰的对象在被释放后,指针仍然指向原对象地址;而weak修饰的对象在被释放之后会自动置指针为nil;- 相同点:在修饰对象的时候,
assign和weak都不改变对象的引用计数。
Q:以下代码会出现什么问题?(深浅拷贝)
@property (copy) NSMutableArray *array;
答:不论赋值过来的是
NSMutableArray还是NSArray对象,进行copy操作后都是NSArray对象(深拷贝)。由于属性被声明为NSMutableArray类型,就不可避免的会有调用方去调用它的添加对象、移除对象等一些方法,此时由于copy的结果是NSArray不可变对象,对NSArray对象调用添加对象、移除对象等方法,就会产生程序异常。
边栏推荐
猜你喜欢

说几个大厂分库分表的那点破事。
![[极客大挑战 2020]Roamphp1-Welcome](/img/3b/2fa91f7478b8abf6efe0feafd24e58.png)
[极客大挑战 2020]Roamphp1-Welcome

JMeter笔记3 | JMeter安装和环境说明
![(18)[系统调用]追踪系统调用(服务表)](/img/05/2529e49932f7bdc9d30f7d267a1d29.png)
(18)[系统调用]追踪系统调用(服务表)

Weka 3.8.6安装与Weka 3.8.6功能介绍

升级 MDK 5.37 后的问题处理: AC6编译选项, printf, 重启失效等

SQLServer下载与安装

Express framework connects MySQL and ORM framework

Wanhua chemical fine chemical industry innovation product assembly

952. 按公因数计算最大组件大小 : 枚举质因数 + 并查集运用题
随机推荐
阿里SIM-基于检索的用户行为兴趣CTR模型(Search-based user Interest Model(SIM))
How Google earth engine realizes the arrangement and selection of our time list
WeChat applet picker scroll selector use detailed explanation
数据库系统原理与应用教程(068)—— MySQL 练习题:操作题 90-94(十二):DML 语句练习
华为无线设备Mesh配置命令
crontab报错,但本地执行正常
Summary of String Copy, Concatenation, Comparison and Split Functions (1)
链表Oj练习题 纯C语言
bert-base调试心得
Mathematical Principles of Graph Convolutional Neural Networks——A Preliminary Study on Spectral Graph Theory and Fourier Transform
华为无线设备配置Mesh业务
关于内和调试无法查看ntdll内存的问题
强烈推荐APP破解常用工具集合!
万华化学精细化工创新产品大会
weiit新零售小程序如何探索数字化门店的破局之路
KDD‘21推荐系统离散特征表征无embedding table Learning to Embed Categorical Features without Embedding Tables for
DLCM - 基于列表上下文信息的重排序模型
图卷积神经网络的数学原理——谱图理论和傅里叶变换初探
腾讯专家献上技术干货,带你一览腾讯广告召回系统的演进
C陷阱与缺陷 第7章 可移植性缺陷 7.3 整数的大小