美文网首页
@property都有哪些修饰词?以及作用总结

@property都有哪些修饰词?以及作用总结

作者: 塞北孤雁 | 来源:发表于2018-03-03 21:31 被阅读0次

    常见的修饰词:assign,weak,strong,retain,copy,nontomic,atomic,readonly,readwrite

    assign(ARC/MRC)

    1.这个修饰词是直接赋值的意思,整型、浮点型等基础数据类型都用该修饰词

    2.如果没有使用weak、strong、retain、copy等词修饰,默认就用assign修饰(他们之间是有你没我的关系,一般的指针类型都用strong修饰)

    3.当然其实对象也可以用assign修饰,只是对象的计数器不会加1.(与strong的区别)

    4.如果用来修饰对象属性 , 那么当对象被销毁后指针是不会指向 nil 的 . 所以会出现野指针错误 ( 与weak的区别 )。

    weak(ARC)(对象)

    1.weak弱指针,修饰对象的修饰词,也就是说它不能修饰基本数据类型(int、float)

    2.weak修饰的对象引用计数器不会加1,也就是直接赋值

    3.弱引用是为打破引用循环而生的

    4.它最被人所喜欢的原因是 它所指向的对象如果被销毁 , 它会指向 nil . 从而不会出现野指针错误 。

    weak 和 assign的区别
    assign和weak,他们都是弱引用类型,但是他们有区别的:

    1.用weak声明的变量在栈中会被自动清空,赋值为nil;

    2.用assign声明的变量在栈中可能不会被赋值为nil,就会造成野指针错误;

    以delegate为例,在MRC中delegate被声明为assign,这是为了不造成循环引用,这时我们需要在dealloc中写上self.delegate = nil;
    以免造成delegate的野指针错误,当然在ARC中只需要用weak声明delegate就可以自动释放了;

    strong(ARC)(对象)

    1.直接赋值,并且对象的引用计数器加1;

    2.在ARC中替代了retain的作用;

    retain(MRC)

    1.release旧对象(旧对象计数器-1),retain新对象(新对象计数器+1),然后指向新对象

    2.在set方法里面是这样写的:

    if(_dog!=nil){
        [_dog release]
    }
    _dog = [dog retain];
    

    copy (ARC/MRC)

    必须要使用copy的情况:(1.属性是一个不可变对象,如NSString,NSArray,NSDictionry;2.需要把一个可变对象赋值给属性,如把一个NSMutableString赋值给属性NSString,除此之外的情况的使用copy和strong是没区别的);

    1.copy在MRC中时是这样做的:release旧对象,旧对象引用计数器减1,retain新对象新对象的引用计数器加1,然后指向新对象(新对象是最终指向的那个对象,不管是深拷贝还是浅拷贝)。在set方法里这样写的

    if(_dog!=nil){
        [_dog release]
    }
    _dog = [dog copy];
    

    2.copy在ARC中是这样干的,copy新对象,新对象的引用计数器加1,然后指向新对象。在set方法里是这样写的:

    _dog = [dog copy];
    

    3.使用注意:

    • 修饰的属性本身必须是不可变的。例如:NSMutableArray采用copy修饰,在addObject时会出现Crash,因为NSMutableArray的对象在copy时就会变成NSArray,如需要拷贝NSMutableArray对象用mutableCopy。
    • 遵守NSCopying协议的对象使用

    nonatomic(ARC/MRC)

    1.不对set、get方法加同步锁

    2.性能好

    3.线程不安全

    atomic(ARC/MRC)

    1.原子属性就是对生成的set方法加互斥锁(互斥锁是一种同步锁,互斥锁:如果共享数据已经有其他线程加锁了,线程会进入休眠状态等待锁,一旦被访问的资源解锁,则等待访问资源的线程会被唤醒。自旋锁:如果共享的数据已经有其他线程加锁了,线程会以死循环的方式等待锁,一旦被访问的资源被解锁,则等待资源的线程会立即执行。自旋锁的效率高于互斥锁)

    @synchronized(锁对象) 。
    @synchronized(self) { _delegate = delegate;}
    

    2.需要消耗系统资源

    3.互斥锁是用线程同步实现的,意在保证同一时间只有一个线程调用set、set方法。

    nonatomic和atomic的介绍和区别

    当使用atomic时,虽然对属性的读和写是原子性的,但是仍然可能出现线程错误:当线程A进行写操作,这时其他线程的读或者写操作会因为等该操作而等待。当A线程的写操作结束后,B线程进行写操作,所有这些不同线程上的操作都将依次顺序执行——也就是说,如果一个线程正在执行 getter/setter,其他线程就得等待。如果有线程C在A线程读操作之前release了该属性,那么还会导致程序崩溃。所以仅仅使用atomic并不会使得线程安全,我们还要为线程添加lock来确保线程的安全。

    更准确的说应该是读写安全,但并不是线程安全的,因为别的线程还能进行读写之外的其他操作。线程安全需要开发者自己来保证。

    相关文章

      网友评论

          本文标题:@property都有哪些修饰词?以及作用总结

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