最近在看即将要加入的项目的代码,看到一个protocol里包含着几个property。之前没有写过类似的代码,看到这里的时候,突然疑惑了一下,发现自己对property的理解好像有点模糊。所以回家后又看了看文档,觉得的确涨了点姿势,所以要记下来~


声明accessor methods

官方文档对property的定义是:

A declared property provides a syntactical shorthand for declaring a class’s accessor methods and, optionally, implementing them.

所以说,声明一个property,实际上等于声明了对应的accessor方法。

对于readwrite的property来说,编译器为它声明了getter方法和setter方法;而对于readonly的property来说,编译器只为它声明了getter方法。
所以,如果想要对readonly的property发送setter消息,编译器就会报错。


合成accessor方法和实例变量

除了声明对应的accessor方法,程序员也可以指示编译器合成accessor方法的实现。

比如,在一个类的implementation block中,使用类似这样的@synthesize语句:

@synthesize firstName = _firstVar;

编译器就会合成firstName这个property的accessor方法的实现和一个叫做_firstVar实例变量

如果只是这样写@synthesize语句:

@synthesize firstName;

那么编译器合成的实例变量的名称也叫firstName


Default Synthesis

从Xcode 4.4和LLVM Compiler 4.0开始,编译器会默认为property合成accessor方法和实例变量,这样程序员就可以不用自己写@synthesize语句了。合成的实例变量的命名规则大概像是这样:

@synthesize firstName = _firstName;

也就是说,合成的实例变量的名字,是property名字前加上了一条下划线。

但是也有一些比较特殊的情况:

  1. 自定义了getter和setter方法的readwrite property
    编译器是不会为这样的property生成默认的实例变量的。如果程序员需要,就得自己添加对应的@synthesize语句了。

  2. 自定义了getter方法的readonly property
    和上面一种情况类似,编译器不会为这样的property生成默认的实例变量。因为这个property是readonly的,编译器自然也不会为它声明和合成setter方法。

  3. Protocol中声明的property
    对于protocol中声明的property,default synthesis是不会作用的。所以,所有实现了这个protocol的类都需要自定义或者用@synthesize语句合成accessor方法和实例变量。

  4. 对于atomic property,不建议自定义getter和setter的其中一个


@dynamic

有的时候,程序员可能想要动态的提供对某个方法的实现。如果希望对property的accessor方法提供动态的实现,就可以使用@dynamic语句。

@dynamic firstName;

这指示了编译器,和这个property有关的方法会动态的提供,这时,即便编译器找不到这个property对应的accessor方法的实现,它也不会报出warning。


关于property的建议

苹果建议,在一般情况下尽量使用accessor方法来访问一个property,而不是直接访问它对应的实例变量。但是在一个对象的init方法deallocate方法自定义的accessor方法中不建议调用accessor方法。


作者:卖萌凉
链接:https://www.jianshu.com/p/455ec3aff322
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

对OC中property的一点理解的更多相关文章

  1. OC中@property属性关键字的使用(assign/weak/strong/copy)

    OC中@property属性关键字的使用(assign/weak/strong/copy) 一.assign 用于 ‘基本数据类型’.‘枚举’.‘结构体’ 等非OC对象类型 eg:int.bool等 ...

  2. OC中property方法的使用

    我们直入主题,关于property方法,我们先来了解一下相关的知识,首先是成员变量,实例变量,属性变量. 我们定义一个类来看一下 @interface Person :NSObject{ NSInte ...

  3. [OC笔记]@property之个人理解,大神轻拍

    /** * 一个简单的对象 * * @author suzhen * */ public class SimpleObjcet { /** * 声明一个age字段 */ private Object ...

  4. [转] iOS (OC) 中 KVC 与 KVO 理解

    转自: http://magicalboy.com/kvc_and_kvo/ KVC 与 KVO 是 Objective C 的关键概念,个人认为必须理解的东西,下面是实例讲解. Key-Value ...

  5. OC 中property的使用

    property在使用的时候需要在其前面加上@符号,需要将其写在类的头文件中 当在定义一个对象的属性变量时,例如定义一个Person类中的name属性,可定义为: @property (nonatom ...

  6. OC中property的有关属性

    property的有关属性: (1)readwrite是可读可写特征:需要生成getter方法和setter方法: (2)readonly是只读特性只会生成getter方法不会生成setter方法: ...

  7. Java中try-catch-finally的一点理解

    在只有try-catch语句中,如果catch块中出现了return语句或者抛出了异常,那么catch之后的语句是执行不到的:但是如果将代码放入finally中,即使catch中出现了return语句 ...

  8. Linux中FTP的一点理解

    FTP(File Transfer Protocol)是一个非常古老并且应用十分广泛的文件传输协议,FTP协议是现今使用最为广泛的网络文件共享协议之一,我们现在也一直有在用着FTP协议来进行各种文件的 ...

  9. vue中mixin的一点理解

    vue中提供了一种混合机制--mixins,用来更高效的实现组件内容的复用.最开始我一度认为这个和组件好像没啥区别..后来发现错了.下面我们来看看mixins和普通情况下引入组件有什么区别?     ...

随机推荐

  1. 前后端分离跨域 关于前后端分离开发环境下的跨域访问问题(angular proxy=>nginx )

    前后端分离后遇到了跨域访问的问题: angular1中使用proxy很麻烦,最后还是失败结束:最后总结3种方法如下: 本人使用的第一种方法,只是开发环境下使用很方便! 1:禁掉谷歌的安全策略(Turn ...

  2. Gradle学习总结

    Gradle学习系列 (1). Gradle快速入门 (2). 创建Task的多种方法 (3). 读懂Gradle语法 (4). 增量式构建 (5). 自定义Property (6). 使用java ...

  3. hiho 1620 - 股票价格3 - 无限制的单调队列?

    题目链接 小Hi最近在关注股票,为了计算股票可能的盈利,他获取了一只股票最近N天的价格A1~AN. 小Hi想知道,对于第i天的股票价格Ai,几天之后股价会第一次超过Ai. 假设A=[69, 73, 6 ...

  4. shell-4.bash的变量:用户自定义变量

    目录 内容

  5. Optional是以enum和泛型为基础的高阶类型

    结论:1.optionals使用时需要检查:2.可以通过!+赋值语句转化为非optionals. Optional-Generic Enumeration enum Optional<T> ...

  6. vue 锚点定位

    vue 锚点定位 <template> <div class="details"> <div class="wrapper w"& ...

  7. Nginx域名配置文件bak

    server { listen 80; server_name m.abd.com; rewrite ^(.*)$ https://$host$1 permanent; } server { list ...

  8. HDU-2204- Eddy’s爱好 (容斥原理)

    题意 给出一个数n,问1-n中有多少个数可以表示为m^k,m,k均为正整数且k>1 (1<=n<=1^18) 题解 (一开始^以为是异或懵逼了好久....) 额,显然1这个数比较讨厌 ...

  9. argparse模块入门介绍——基于python3.7

    转载:https://blog.csdn.net/weixin_41796207/article/details/80846406 首先说明,本人是想要学习如何使用argparse模块,打造命令行程序 ...

  10. 紫书 习题8-18 UVa 11536 (扫描法)

    这道题貌似可以用滑动窗口或者单调栈做, 但是我都没有用到. 这道题要求连续子序列中和乘上最小值最大, 那么我们就可以求出每一个元素, 以它为最小值的的最大区间的值, 然后取max就ok了.那么怎么求呢 ...