美文网首页将来跳槽用iOS基础知识
一举拿下ios属性的关键字

一举拿下ios属性的关键字

作者: 二斤寂寞 | 来源:发表于2019-04-10 17:51 被阅读16次
    attributes
    Attributes Attributes
    atomic nonatomic
    strong weak
    readwrite readonly
    getter setter
    copy assign
    retain unsafe_unretained

    atomic

    如果没有指明是nonatomic的,那么默认就是atomic。atomic的意思是数据的读写是线程安全的,这在多线程的时候非常有用,但是与nonatomic相比的话效率会低很多。所以为了提升效率,除非是在明确知道对象会在多线程中使用,否则尽量使用nonatomic关键字。

    nonatomic

    nonatomic不能保证数据的原子性,也就是说在多线程访问的时候不能保证能够正确读取数据,甚至有可能发生崩溃。如果使用了nonatomic关键字,这时候如果存在多线程访问的话,需要自己来处理线程的安全问题。

    retain

    ARC之前使用的关键字,ARC之后用strong代替。

    strong

    这是一个ARC之后才有的属性,在使用ARC的时候,这是一个默认属性。与它对应的是weak属性。strong使类能够拥有对象的所有权,会增加对象的 retain count 以保证在类使用该对象的时候,对象没有被销毁。strong可能会导致retain cycle,要谨慎使用,常使用在继承自NSObject的类和大部分自定义类
    官方文档介绍:

    // The following declaration is a synonym for: @property(retain) MyClass *myObject;
    @property(strong) MyClass *myObject;
    

    表示了strong和retain是同义词。

    unsafe_unretained

    ARC之前使用的关键字,类似于weak,但与weak不同的是在对象被销毁后,指针不会被置为空,所以有可能会造成崩溃

    Paste_Image.png

    weak (weak 对象释放的时候,怎么置为nil的呢?请阅读iOS 底层解析weak的实现原理

    只是将指针指向该对象,但是并没有对象的所有权,在对象被释放的时候,weak指针会被置为nil,这保证了指针的安全, 在OC里是可以给nil对象发送消息而不会崩溃的,但是如果给一个被释放的对象发送消息就会崩溃了。weak不会增加对象的 retain count

    assign

    简单数据类型(int,long,double, float,Bool)默认就是assign的,不改变对象的retainCount。最好是只在简单数据类型时使用,对于对象类型,最好不要使用

    readwrite

    所有的属性默认都是readwrite的,使用readonly关键字可以覆盖该默认值。

    readonly

    表示对象是只读的。当我们不希望外面的类可以修改该属性的时候,可以在头文件中将属性定位readonly,但是在实现文件中,我们可以将它声明为readwrite,这样就只能在类内部才能修改这个属性了。

    getter

    指定get方法, 并需要实现这个方法. 必须返回与声明类型相同的变量,没有参数.

    setter

    指定 set 方法, 并需要实现这个方法. 带一个与声明类型相同的参数, 没有返回值(返回nil)当声明为 readonly 的时候, 不能指定 set 方法.
    默认情况下,系统会生成一个与属性同名的getter、setter 方法,

    copy copy还是strong?用copy还是mutablecopy

    与strong不同的是,copy不会增加对象的 retain count
    而是会重新复制一份对象,然后将指针指向新复制的对象。
    使用copy关键字的属性的类型必须遵循NSCopying协议。
    含有可深拷贝NSCopy子类的类,如NSArray,NSSet, NSDictionary, NSData, NSCharacterSet, NSIndexSet, NSString 等一般都用copy来修饰. 这是因为父类的指针可以指向子类对象, 使用copy的目的就是为了对象本身不受外界影响, 无论传给我一个可变还是不可变的对象, 我本身持有的都是一个不可变对象.

    假如有一个属性是NSString类型的,但是我们却将一个NSMutableString赋值给了它(这是合法的),如果我们使用strong关键字,那么现在这个对象是一个NSMutableString的对象,如果在别的地方修改了这个对象的值,那么该属性也跟着变了,这可能会带来意想不到的后果。但如果我们使用copy关键字的话,就不会存在这个问题了,因为它会拷贝一份NSMutableString的值,这时属性依然是 immutable 的,即使NSMutableString的对象修改了也不会影响属性的值。

    Block为什么使用copy修饰

    DemoBlock内部没有调用外部变量时存放在全局区(ARC和MRC下均是)
    DemoBlock2使用了外部变量,这种情况也正式我们平时所常用的方式,Block的内存地址显示在栈区,栈区的特点就是创建的对象随时可能被销毁,一旦被销毁后续再次调用空对象就可能会造成程序崩溃,在对block进行copy后,block存放在堆区.所以在使用Block属性时使用Copy修饰,而在ARC模式下,系统也会默认对Block进行copy操作

    @synthesis

    告诉编译器自动生成属性的 getter 和 setter 方法,并且为属性绑定一个成员变量,也就是说将属性的访问器方法作用于绑定的成员变量。正常情况下可以不使用@synthesis关键字,编译器也会默认生成访问器方法,在一些特殊情况下,需要明确使用@synthesis关键字才能生成访问器方法,包括以下情况:

    • 绑定非默认的实例变量。
      默认情况下,系统会生成一个_ 的成员变量与属性绑定在一起,如果不想使用系统生成的成员变量的话,可以通过@synthesis name = customName来绑定一个自定义的成员变量名。

    • 协议中定义的属性。
      当类实现的协议中包含属性时,必须在类中明确使用@synthesis才能生成访问器方法

    • 重写访问器方法。
      在重写 getter 和 setter 的时候需要用与属性相关的成员变量,由于重写了 getter 和 setter ,系统不会在默认合成这两个方法,也不会默认生成一个带下划线的成员变量,这时需要使用@synthesis关键字来定一个与属性对应的成员变量。

    • 类别(category)中定义的所有属性

    • 重载的属性
      重写了 setter 和 getter 或者只读属性的getter时

    @dynamic

    目的是告诉编译器访问器方法没有本类中实现,而是在别的地方(比如父类)中实现了,编译器就不会再发出警告了。主要是用在CoreData的NSManagedObject子类中。

    相关文章

      网友评论

        本文标题:一举拿下ios属性的关键字

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