深入理解@property

看文章之前,我们先思考下,@property 为什么会存在,它的意义在于什么?我们普通定义的变量和用@Property定义的有什么区别?如果只是作用域的问题,那么跟public的成员变量有何区别?以及@Property后面括号里的各个关键字的作用。希望看完此文能够解开这些迷惑,更好的理解@Property和对它更好的运用。

首先我们先来看下什么是@property ,Objective-C语言关键词,与@synthesize配对使用。xcode4.5以及以后的版本,@synthesize可以省略。

声明property的语法为:@property (参数1,参数2) 类型 名字;
如:
@property(nonatomic,retain) UIWindow *window;

其中括号里的参数主要分为三类:
读写属性:
(readwrite/readonly/setter = /getter = )

setter语意:
(assign/retain/copy)

原子性:
(atomicity/nonatomic)

各参数意义如下:
readwrite
产生setter\getter方法

readonly
只产生简单的getter,没有setter, 默认的读写属性.

setter =
指定生成setter方法的名字

getter =
指定生成getter方法的名字

assign
默认类型,setter方法直接赋值,而不进行retain操作, 适用于基本数据类型, 对对象类型, 不会发生引用计数变化.

retain
setter方法对参数进行release旧值,再retain新值。

copy
setter方法进行Copy操作,与retain一样,使用copy:对NSString类型 关于copy以后会写一篇文章专门说说

atomic
保证多线程访问下的安全, 但浪费系统资源, 原子性控制的默认设置.

nonatomic
禁止多线程,变量保护,提高性能
指出访问器不是原子操作,而默认地,访问器是原子操作。这也就是说,在多线程环境下,解析的访问器提供一个对属性的安全访问,从获取器得到的返回值或者通过设置器设置的值可以一次完成,即便是别的线程也正在对其进行访问。如果你不指定nonatomic,在自己管理内存的环境中,解析的访问器保留并自动释放返回的值,如果指定了nonatomic,那么访问器只是简单地返回这个值。

还有strong与weak是由ARC新引入的对象变量属性
xcode 4.2(ios sdk4.3和以下版本)和之前的版本使用的是retain和assign,是不支持ARC的。xcode 4.3(ios5和以上版本)之后就有了ARC,并且开始使用
strong与weak
简单讲strong等同retain weak等同于assign。只是根据mrc和arc的时候选择使用。

unsafe_unretained
unsafe_unretained 就是ios5版本以下的 assign ,也就是 unsafe_unretained , weak, assign 三个都是一个样的。 因为 ios5用的是 weak ,那在ios4.3就用不了,如果你将 weak 修改为 unsafe_unretained ,那就可以用了。说到底就是iOS 5之前的系统用该属性代替 weak 来使用。

关于unsafe_unretained , weak, assign用于非指针变量。用于
基础数据类型 (例如NSInteger)和C数据类型(int, float, double, char, 等),另外还有id
反正记住:前面不需要加 “*” 的就根据MRC和ARC 以及 iOS sdk来选择使用 unsafe_unretained , weak, assign吧 。

strong\retain:用于指针变量。就是说你定义了一个变量,然后这个变量在程序的运行过程中会被更改,并且影响到其他方法。一般是用于字符串( NSString,NSMutableString),数组(NSMutableArray,NSArray),字典对象,视图对象(UIView ),控制器对象(UIViewController)等
xcode 4.2不支持ARC,所以会频繁使用retain来修饰,用完释放掉,而xcode4.3支持ARC,可以使用retian,不需要手动释放内存,系统会自动为你完成,如果你在xcode4.3上面开发,retian和strong都是一样的,没区别

在内存方面assign是被自动释放的,retain是需要手动去释放。

关于为什么sb拖出的控件默认用的是weak而不是strong ,在知乎上有人给出了答案:
IBOutlet的属性一般可以设为weak是因为它已经被view引用了,除非view被释放,否则IBOutlet的属性也不会被释放,另外IBOutlet属性的生命周期和view应该是一致的,所以IBOutlet属性一般设为weak。如果你那个Outlet 是在第一层 不是在view上的就是 strong的

以上纯属个人理解,有不对的地方请指出,谢谢。

知乎连接:http://www.zhihu.com/question/29927614?sort=created

这里补充几个新的大家看看了解一下:
1.nonnull
@property (nonnull, nonatomic, strong) NSString *name;
nonnull : 标示当前属性不为空,让外界放心用,只做标示用,即使为空,也木有办法
相当于swift里面的 ! 号

2..nullable
@property (nullable, nonatomic, strong) NSString petName;
nullable : 标示当前属性可能为空,让外界使用时注意
相当于swift里面的 ? 号
3.<Person
>
@property (nullable , nonatomic, strong) NSArray *friends;
有点类似于泛型和id的结合,目的是告诉开发人员,数组内装的什么鬼
代表数组内的对象 is kind of 所填的类型 , 当开发人员用的时候不需要再进行从父类强转到子类

那么说了这么多:@property它的存在意义是什么呢? 我个人理解就是自动生成setter getter方法。@property是给编辑器看的。就算你不声明@property,在obj的@implenmention下写好valueA和setValueA,还是可以obj.valueA赋值或取值,但是没有自动联想。还有一个区别是:@property 可以更好的管理内存,我们在括号里写的关键字定义就是。 和public的成员变量有何区别:property可以自己实现存取方法。

以上有的是摘自别人的总结,我感觉很对就拿来了,有什么大家觉得理解不一样的,可以说出来讨论讨论。

我相信此片文章只是浅谈了一下,希望大家能够更深的交流,我也会及时补充一些。