美文网首页
ios 修饰词作用

ios 修饰词作用

作者: 小小SnowGo | 来源:发表于2017-03-17 10:56 被阅读0次

    修饰词:assign、weak、strong、retain、copy、nonatomic、atomic、readonly、readwrite

    其中

    ARC:assign、weak、strong、copy

    MRC:assign、retain、copy、nonatomic、atomic

    assign ( ARC/MRC )

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

    2.如果没有使用 weak strong retain copy 修饰 , 那么默认就是使用 assign 了. ( 它们之间是有你没我的关系 )

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

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

    weak ( ARC )(对象)

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

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

    3.弱引用是为打破循环引用而生的,比如在Block中,block在copy的时候,会对内部使用到的对象的引用技术+1,如果使用[self 方法名],那么就会有一个强指针指向self所在的class的内存地址,class的引用计数会+1,这样一来会导致class所在的内存地址无法被释放,造成内存泄漏 .

    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 )

    1.copy 在 MRC 时是这样做的 release 旧对象( 旧对象的引用计数器 -1 ) , copy 新对象( 新对象的引用计数器 +1 ) , 然后指向新对象 .(新对象是指最终指向的那个对象,不管深拷贝还是浅拷贝)

    1.1在set方法里面是这样的 :

    if (_dog != nil)

    {

    [_dog release];

    }

    _dog = [dog copy];

    2.copy 在 ARC 时是这么干的 copy 新对象( 新对象的引用计数器 +1 ) , 然后指向新对象 .

    2.1在set方法里面是这样的 :

    _dog = [dog copy];

    3.使用注意 :

    3.1 修饰的属性本身要不可变的。例如 NSMutableArray 采用 copy 修饰 , 在addObject时会出现Crash, 因为NSMutableArray的对象在copy 过后就会变成NSArray。如果需要copy NSMutableArray对象,用:mutablecopy。

    3.2 遵守 NSCopying 协议的对象使用 .

    nonatomic ( ARC/MRC )

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

    2.性能好

    3.线程不安全

    atomic ( ARC/MRC )

    1.原子属性就是对生成的 set 方法加互斥锁 @synchronized(锁对象) .

    @synchronized(self) { _delegate = delegate;}

    2.需要消耗系统资源 .

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

    4.其实还有 get 方法 , 要是同时 set 和 get 一起调用还是会有问题的 . 所以即使用了 atomic 修饰 还是不够安全 .

    nonatomic 和 atomic 的介绍和区别

    1. 什么是atomicity(原子性)?

    atomicity(原子性):我把原子性理解成线程对属性的单一执行。

    例如,当两条线程同时执行一个属性的set方法的时候,如果不具有原子性(也就是声明属性时使用了nonatimic),那么就可能出现当A线程正在改写某属性值的时候,B线程也许会突然闯入,把尚未修改好的属性值读取出来。发生这种情况时,线程读取到的属性值肯能不对。

    2. 保证atomicity真的就线程安全了吗?为什么日常声明都用的是nonatomic呢?

    1.保证atomicity并非也是线程安全的,如果需要保证安全,需要跟深层次的线程锁定机制。

    2.使用同步锁在iOS中开销比较大,会给程序带来性能上的问题。

    3. 为什么atomicity也不能保证线程安全?

    例如:当使用atomic时,仍然可能出现线程错误:当线程A进行set操作,这时其他线程的get或者set操作会因为等该操作而等待。当A线程的set操作结束后,B线程进行set操作,然后当A线程需要get操作时,却获得了在B线程的值,这就破坏了线程安全,如果有C线程在A线程get操作之前release了该属性,那么还会导致程序崩溃。所以仅仅使用atomic并不会使得线程安全,我们还是要为线程添加lock来确保线程的安全。

    readonly (只读)

    1.让 Xcode 只生成get方法 .

    2.不想把暴露的属性被人随便替换时 , 可以使用 .

    readwrite (读写)(默认)

    1.让 Xcode 生成get/set方法 .

    2.不用 readonly 修饰时 , 默认就是 readwrite .

    相关文章

      网友评论

          本文标题:ios 修饰词作用

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