Effective Objective-C 2.0之Note.03(属性详解)
用Objective-C等面向对象语言编程时,“对象”(object)就是“基本构造单元”(building block),开发者可以通过对象来存储并传递数据。在对象之间传递数据并执行任务的过程就叫做“消息传递”(Messaging)。
“属性”(property)是Objecive-C的一项特性,用于封装对象中的数据。
当应用程序运行起来以后,为其提供相关支持的代码叫做“Objective-C运行期环境”(Objective-C runtime),它提供了一些使得对象之间能够传递消息的重要函数,并且包含创建类实例所用的全部逻辑。
如果使用了属性的话,那么编译器就会自动编写访问这些属性所需的方法,此过程叫做“自动合成”(autosynthesis)。需要强调的是,这个过程由 编译器在编译期执行,所以编辑器里看不到这些“合成方法”(synthesized method)的源代码。除了生成方法代码之外,编译器还要自动向类中添加适当类型的实例变量,并且在属性名前面加下划线,以此作为实例变量的名字。
若不想令编译器自动合成存取方法,则可以自己实现。如果你只实现了其中一个存取方法,那么另外一个还是会由编译器来合成。还有一种办法能阻止编译器自动合 成存取方法,就是使用@dynamic关键字,它会告诉编译器:不要自动创建实现属性所用的实例变量,也不要为其创建存取方法。而且,在编译访问属性的代 码时,即使编译器发现没有定义存取方法,也不会报错,它相信这些方法能在运行期找到。比方说,如果从CoreData框架中的 NSManagedObject类里继承了一个子类,那么就需要在运行期动态创建存取方法。继承NSManagedObject时之所以要这样做,是因为 子类的某些属性不是实例变量,其数据来自后端的数据库中。例如:
@interface EOCPerson : NSManagedObject
@property NSString *firstName;
@property NSString *lastName;
@end @implementation EOCPerson
@dynamic firstName, lastName;
@end
属性可以拥有的特质分为四类:
原子性
在默认情况下,由编译器所合成的方法会通过锁定机制确保其原子性(atomicity)。如果属性具备nonatomic特质,则不使用同步锁。请 注意,尽管没有名为“atomic”的特质(如果某属性不具备nonatomic特质,那它就是“原子的”(atomic)),但是仍然可以在属性特质中 写明这一点,编译器不会报错。若是自己定义存取方法,那么就应该遵从与属性特质相符的原子性。
atomic与nonatomic的区别是什么呢?前面说过,具备atomic特质的获取方法会通过锁定机制来确保其操作的原子性。这也就是说,如果两个 线程读写同一属性,那么不论何时,总能看到有效的属性值。若是不加锁的话(或者说使用nonatomic语义),那么当其中一个线程正在改写某属性值时, 另外一个线程也许会突然闯入,把尚未修改好的属性值读取出来。发生这种情况时,线程读到的属性值可能不对。
开发iOS程序时应该使用nonatomic属性,因为atomic属性会严重影响性能。
读/写权限
具备readwrite(读写)特质的属性拥有“获取方法”(getter)与“设置方法”(setter)。若该属性由@synthesize实现,则编译器会自动生成这两个方法。
具备readonly(只读)特质的属性仅拥有获取方法,只有当该属性由@synthesize实现时,编译器才会为其合成获取方法。你可以用此特 质把某个属性对外公开为只读属性,然后在“class-continuation分类”中将其重新定义为读写属性。
内存管理语义
属性用于封装数据,而数据则要有“具体的所有权语义”(concrete ownership semantic)。下面这一组特质仅会影响“设置方法”。例如,用“设置方法”设定一个新值时,它是应该“保留”(retain)此值呢,还是只将其赋 给底层实例变量就好?编译器在合成存取方法时,要根据此特质来决定所生成的代码。如果自己编写存取方法,那么就必须同有关属性所具备的特质相符。
assign “设置方法”只会执行针对“纯量类型”(scalar type,例如CGFloat或NSInteger等)的简单赋值操作。
strong 此特质表明该属性定义了一种“拥有关系”(owning relationship)。为这种属性设置新值时,设置方法会先保留新值,并释放旧值,然后再将新值设置上去。
weak 此特质表明该属性定义了一种“非拥有关系”(nonowning relationship)。为这种属性设置新值时,设置方法既不保留新值,也不释放旧值。此特质同assign类似,然而在属性所指的对象遭到摧毁时,属性值也会清空(nil out)。
unsafe_unretained 此特质的语义和assign相同,但是它适用于“对象类型”(object type),该特质表达一种“非拥有关系”(“不保留”,unretained),当目标对象遭到摧毁时,属性值不会自动清空(“不安 全”,unsafe),这一点与weak有区别。
copy 此特质所表达的所属关系与strong类似。然而设置方法并不保留新值,而是将其“拷贝”(copy)。当属性类型为NSString* 时,经常用此特质来保护其封装性,因为传递给设置方法的新值有可能指向一个NSMutableString类的实例。这个类是NSString的子类,表 示一种可以修改其值的字符串,此时若是不拷贝字符串,那么设置完属性之后,字符串的值就可能会在对象不知情的情况下遭人更改。所以,这时就要拷贝一份“不 可变”(immutable)的字符串,确保对象中的字符串值不会无意间变动。只要实现属性所用的对象是“可变的”(mutable),就应该在设置新属 性值时拷贝一份。
方法名
可通过如下特质来指定存取方法的方法名:
getter=<name> 指定“获取方法”的方法名。如果某属性是Boolean型,而你想为其获取方法加上“is”前缀,那么就可以用这个办法来指定。比如说,在UISwitch类中,表示“开关”(switch)是否打开的属性就是这样定义的: @property (nonatomic, getter=isOn) BOOL on;
setter=<name> 指定“设置方法”的方法名。这种用法不太常见。
Effective Objective-C 2.0之Note.03(属性详解)的更多相关文章
- 机器学习03 /jieba详解
机器学习03 /jieba详解 目录 机器学习03 /jieba详解 1.引言 2.分词 2.1.jieba.cut && jieba.cut_for_search 2.2.jieba ...
- mysql-8.0.16-winx64.zip安装教程详解
摘自:https://zhuanlan.zhihu.com/p/48531203 mysql-8.0.16-winx64.zip安装教程详解下载地址:https://dev.mysql.com/get ...
- Spark2.1.0——内置Web框架详解
Spark2.1.0——内置Web框架详解 任何系统都需要提供监控功能,否则在运行期间发生一些异常时,我们将会束手无策.也许有人说,可以增加日志来解决这个问题.日志只能解决你的程序逻辑在运行期的监控, ...
- Spark2.1.0——内置RPC框架详解
Spark2.1.0——内置RPC框架详解 在Spark中很多地方都涉及网络通信,比如Spark各个组件间的消息互通.用户文件与Jar包的上传.节点间的Shuffle过程.Block数据的复制与备份等 ...
- MySQL 8.0.20 安装教程图文详解(windows 64位)
MySQL 8.0.20 安装教程图文详解(windows 64位) 更新时间:2020年05月09日 15:09:04 转载 作者:瘦肉粥不加糖 这篇文章主要介绍了MySQL 8.0. ...
- MySQL8.0.20安装教程图文详解,MySQL8.0.20安装教程winodws10
MySQL8.0.20安装教程图文详解,非常详细 一:mysql官网下载 https://dev.mysql.com/downloads/file/?id=494993 不用注册,直接下载就好 二:解 ...
- struts2.0中struts.xml配置文件详解
先来展示一个配置文件 <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration ...
- Android Studio3.0的下载及其安装详解加eclipse下载安装配置jdk9
关注我,每天都有优质技术文章推送,工作,学习累了的时候放松一下自己. 本篇文章同步微信公众号 欢迎大家关注我的微信公众号:「醉翁猫咪」 今天我们来讲解如何下载android studio 3.0及其 ...
- [转]OAuth 2.0 - Authorization Code授权方式详解
本文转自:http://www.cnblogs.com/highend/archive/2012/07/06/oautn2_authorization_code.html I:OAuth 2.0 开发 ...
随机推荐
- Vmware ESX5i 环境下部署Windows Storage Server 2008 R2
ESX5i 环境下部署Windows Storage Server 2008 R2 Windows Storage Server 2008 这款产品微软早已发布,WSS2008是基于Win ...
- windows7安装远程服务器AD域管理工具
目的:在win7上安装“远程服务器管理工具”,这样可以在客户端进行对服务器的AD域的操作,避免了远程登陆进服务器的麻烦. 前提条件:一般此工具只有管理员才具有有效使用权限,所以,在域administr ...
- vm虚拟机里的桥接模式下“复制物理网络连接状态”作用
前提:真实主机可以上网 勾选,虚拟机也可以上网 不勾选,虚拟机不可以上网
- Java移位运算
java中移位运算符有三种“<<”.“>>”.“>>>”,没有“<<<”运算符. “<<”运算符将二进制位进行左移,低位用0来填 ...
- 根据之前的博文,我把给同学做的三子棋小游戏的代码发出来,只是界面很丑很丑,AI算法很笨很笨,过几天我传到网盘上,提供大家下载娱乐
background_image_filename = 'blackground.png' black_mouse_image_filename = 'black.png' white_mouse_i ...
- com.google.inject.CreationException: Guice creation errors
错误的原因:xml文件中方法名重复或错误
- grub2
手工启动 set root(hd0,msdos7) linux /boot/vmlinuz-3.9.8-300.fc19.i686.PAE root=/dev/sda7 initrd /boo ...
- VMware vSphere Client的简单使用教程
1.首先登陆进去ESXI管理 实验VMware VS6.0版本 2新建虚拟机 确认信息 点击完成 2.开启虚拟机 右键打开控制台 加载光驱 选择虚拟机 Ctrl+Alt+delete重启 安装 来 ...
- jquery美化select,自定义下拉框样式
select默认的样式比较丑,有些应用需要美化select,在网上找到一个很好的美化样式效果,本人很喜欢,在这里分享一下. <!DOCTYPE html PUBLIC "-//W3C/ ...
- 配置Nginx服务
一,安装之前准备1.nginx依赖: gcc openssl-devel pcre-devel zlib-devel 安装依赖:yum install gcc openssl-devel pcr ...