属性

作者: 愤怒的八哥 | 来源:发表于2019-02-12 16:09 被阅读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

    相关文章

      网友评论

          本文标题:属性

          本文链接:https://www.haomeiwen.com/subject/ufiheqtx.html