[关闭]
@universal 2018-11-29T10:55:35.000000Z 字数 2228 阅读 374

iOS入门——@property属性

iOS


入门

@property属性详解
属性大概分为三个方面:原子性、存取、内存管理:
1. nonatomic / atomic
2. readonly / readwrite
3. retain / copy / strong / weak /assign

我的理解:property属性的核心主要是实现变量的getter和setter方法(然后就可以通过点语法获取变量),在此之上,附加的关键字不同,预编译的实现也有区别,所以功能也不同。

这里概括下:@property 声明属性其实是做了三件事:


一、 首先是线程安全:

atomic(系统默认),在多线程环境下,利用aotmic保证线程安全。内部主要是通过自旋锁实现,而且保证的也是读写操作的原子性,并没有实际上我们想要的线程安全。所以一般线程安全还需要我们在外部自己实现。

nonatomic 跟atomic相反,可以被多个线程同时访问,效率较高但是安全性较低。比如:

  1. - (UITextField *) userName {
  2. return userName;
  3. }

二、存取方法:

readwrite(系统默认):可读可写,表明该属性同时拥有setter和getter方法。

readonly:只读属性,只有getter方法,不希望属性在类外被改变。

@synthesize:编译器在.m中自动合成getter和setter的实现(主要由编译器在编译器执行),但是这个在xcode4.5以后就不需要了,一个property就能搞定。
@dynamic:属性的getter和setter方法由用户自己实现,编译器不自动生成。这个时候还需要我们显示的声明下属性。

三、内存管理:

copy:内容拷贝。copy属性会在赋值前,复制一个对象,这个copy修饰的属性(变量)会指向一个新对象,所以原对象的改变就不会影响新值的变化。使用:防止属性被意外修改。所有mutable(可变)的属性类型,如NSString, NSArray, NSDictionary等等,(对应可变的类型:NSMutableString, NSMutableArray,NSMutableDictionary)这些非可变类型在属性赋值时,右边的值有可能是它们的可变版本。这样就会出现属性值被意外改变的可能。所以它们都应该用copy。

  1. //应用copy属性:
  2. - (void)setNameCopy:(NSString *)nameCopy {
  3. _nameCopy = [nameCopy copy];
  4. }

注: 所以如果用copy修饰NSMutableString、NSMutableArray会出错,因为在set的时候,会将原本mutable的对象,copy成了immutable的对象。

strong(ARC中默认):强引用,表示实例变量对传入的对象要有所有权关系。使用:对象类型,比如自定义对象,控制器对象。

weak:弱引用,在setter方法中,对传入的对象不进行引用计数加1的操作,当该对象引用计数为0时,即该对象被释放后,用weak声明的实例变量指向nil。使用:代理对象(在delegate patterns中常用weak解决strong reference cycles(以前叫retain cycles)问题),IBOutlet。

assign:非ARC时代的特性,作用和weak类似:简单赋值,不改变引用计数,但是不同的是如果对象被销毁,指向该对象的assign属性并不会设置为nil,这时候再访问这些属性就会crash。在ARC下,assign适用于基本数据类型(默认)。使用:int、float、double、BOOL、NSInteger等。
retain:指针拷贝,非ARC的特性,现在在ARC中已经不怎么使用了。与strong功能一致。

四、其他:

getter= 和 setter= :重命名getter和setter方法,在ARC中存取方法不能以new开头,所以不能以new开头命名一个属性,比如:

  1. @property (copy, nonatomic) NSString *newName;

这样就会报错,解决办法:

  1. @property (copy, nonatomic, getter=theNewName) NSString *newName;

Nullability


总结、

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注