属性

2019-02-12  本文已影响1人  愤怒的八哥

属性修饰符

种类 选项 说明
指定方法名 getter = getter 方法名 setter = setter 方法名 显式指定getter方法和setter方法的名字
读写属性 readonly 只读
readwrite 读写 默认
赋值时的选项 assign 单纯赋值
retain 进行保持操作
unsafe_unretained 同assign 一样 (用于 ARC)
strong 同retain 一样 (用于 ARC 默认
weak 弱引用(用于 ARC)
copy 复制对象
原子性操作 nonatomic 非原子性操作、非线程安全
atomic 原子性、线程安全 默认

赋值时不是对象类型
不需要指定任何选项,也可以指定为assign。
属性时对象类型,且使用ARC
assign或者unsafe_unretained选项,只进行单纯的赋值,不进行保持操作。所以成员变量指向的内容有可能被释放掉而变成野指针,这就是为什么代理使用weak修饰符而不用assign。
指定为strong或者weak,如果又显式的写出成员变量名称,则需要加上相应的修饰符__strong或者__weak
修饰符为 copy则会传入一份副本,并用这份副本给实例变量进行赋值。
注意下面
在声明名属性时,就会有一些不成文的规范。以字符串为例,为了保障数据的安全,以免被随意修改,尽量使用NSString(非mutable)类型,若不希望该属性内容的随着外部变化而影响初始值,应该用copy修饰,甚至用readonly 加强修饰。若希望该属性的内容随时变化并存储,可以用strong修饰,NSMutable* 类,都是继承自NS类,因此,NS 可以接收NSMuatble* 或NS * 类型的值,调用NS* 相关属性或方法,是正常的操作。或声明成NSMutableString类型,切记一定要用strong修饰。
推荐的属性声明方式:
@property (nonatomic, copy) NSString *copyedString;
@property (nonatomic, strong) NSMutableString *strongMutableString;
根据需要选择,NSArray、NSMutableArray; NSDictionary、NSMutableDictionary; NSSet、NSMutableSet;类似。


用@property声明 NSString、NSArray、NSDictionary 、Block经常使用copy关键字
是因为他们有对应的可变类型:NSMutableString、NSMutableArray、NSMutableDictionary,他们之间可能进行赋值操作,为确保对象中的字符串值不会无意间变动,应该在设置新属性值时拷贝一份。
Block使用copy因为在MRC中,方法内部的Block是在栈区的,使用copy可以把它放到堆区.在ARC中写不写都行:对于Block使用copy还是strong效果是一样的,但写上copy也无伤大雅,还能时刻提醒我们:编译器自动对Block进行了copy操作。
atomic
如果访问方法是原子性的,那就意味着多线程环境下访问属性是安全的,在执行的过程中不可被打断。而nonatomic恰好好相反。
指定了atomic,getter和setter方法的实现里面用lock来保证线程读写安全。
如果多个线程同时调用getter或setter,就有可能会出现值丢失或内存泄漏。通过用lock能够保证每次最多一个线程执行lock和unlock之间的代码,从而保证原子性。
对于频繁使用且不考虑多线程竞争的,可以在声明的时候加上nonatomic。
该属性使用了同步锁,会在创建时生成一些额外的代码用于帮助编写多线程程序,这会带来性能问题,通过声明nonatomic可以节省这些虽然很小但是不必要额外开销。
在默认情况下,由编译器所合成的方法会通过锁定机制确保其原子性(atomicity)。如果属性具备nonatomic特质,则不使用同步锁。请注意,尽管没有名为“atomic”的特质(如果某属性不具备nonatomic特质,那它就是“原子的”(atomic))。
关于atomic是否安全:

https://blog.csdn.net/h_qiao/article/details/79041375

@synthesize

从Xcode4.4以后@property已经独揽了@synthesize的功能
主要有三个作用:

(1)生成了成员变量get/set方法的声明
(2)生成了私有的带下划线的的成员变量因此子类不可以直接访问,但是可以通过get/set方法访问。那么如果想让定义的成员变量让子类直接访问那么只能在.h文件中定义成员变量了,因为它默认是@protected
(3)生成了get/set方法的实现

注意:
如果已经手动实现了get和set方法的话Xcode不会再自动生成带有下划线的私有成员变量了
因为xCode自动生成成员变量的目的就是为了根据成员变量而生成get/set方法的
但是如果get和set方法缺一个的话都会生成带下划线的变量


在Xcode4.4版本之前@property和@synthesize的功能是独立分工的:

@property的作用是:自动的生成成员变量set/get方法的声明如代码:
@property int age; 它的作用和下面两行代码的作用一致
- (void)setAge:(int)age;
- (int)age;
注意:属性名称不要加前缀_ 否则生成的get/set方法中也会有下划线

@synthesize的作用是实现@property定义的方法代码如:
@synthesize age
将@property中定义的属性自动生成get/set的实现方法而且默认访问成员变量age
如果指定访问成员变量_age的话代码如:
@synthesize age = _age;意思是:
把@property中声明的age成员变量生成get/set实现方法,并且在实现方法内部
访问_age这个成员变量,也就意味着给成员 _age 赋值

注意:访问成员变量 _age 如果在.h文件中没有定义_age成员变量的话,就会在.m文件中自动生成@private类型的成员变量_age

上一篇下一篇

猜你喜欢

热点阅读