美文网首页
iOS中的assign,retain,copy,weak,sto

iOS中的assign,retain,copy,weak,sto

作者: 彬至睢阳 | 来源:发表于2018-05-12 10:59 被阅读0次

    iOS中的OC是一门面向对象的编辑语言,每一个对象都是类的实例,在OC中每一个对象都有一个名为isa的指针,指向该对象的类。所有NSObject是一个包含isa指针的结构体。

    1.强弱引用的区别

     (1) assign 和 weak 一样是一个弱引用;

      (2) strong是强引用;

    区别:他们最重要的区别是引起内存的变化和内存管理,在setter方法赋值过程中,指针的数值会发生变化。如:

    (1)- property(nonatomic, assign)NSObject * a;

                - (void)setA:(int) a {

                 - a = a;

                 }

              在弱引用的情况下,直接进行赋值,即原本指针的值为1,赋值以后没有将指针的数字增大,还是1;

    (2)- property(nonatomic, strong)NSObject * a;

       - (void)setA:(int) a {

                [_a release];

                 - a = [a strong];

                 }

     在强引用的情况下,进行+1之后再赋值,使用过后-1仍然是1,返回之前的状态,置为nil。

             而assign,在使用之后也不进行-1,还是1,但是指向的东西却没有了,总是没有变化,也不会指向nil,所以就会发生混乱。

     assign和weak的区别

     本质区别

     速度比较: __unsafe_unretained > __weak

    @property (nonatomic, assign) Person *person;  // 真实类型是 Person *__unsafe_unretained _person;

    __unsafe_unretained的特点:

    1.不是强引用, 不能保住OC对象的命

    2.如果引用的OC对象销毁了, 指针并不会被自动清空, 依然指向销毁的对象(很容易产生野指针错误: EXC_BAD_ACCESS)

    @property (nonatomic, weak) Person *person;  // Person * _Nullable __weak person;

    __weak的特点:

    1.不是强引用, 不能保住OC对象的命

    2.如果引用的OC对象销毁了, 指针会被自动清空(变为nil), 不再指向销毁的对象(永远不会产生野指针错误).可以归纳为弱引用在对象释放后置为nil,避免了错误的内存访问,及weak可以在不增加对象的引用计数的同时,又使得指针的访问是安全的

    - 用途

    - assign一般用在基本数据类型上面, 比如int\double等

    - weak一般用在代理对象上面, 或者用来解决循环强引用的问题

     assign:  简单的直接赋值,相当于说两个对象指向同个内存区,一个地方的变了,其他的也跟着改变。

    copy: 用于希望保持一份传入值的拷贝,而不是值自身的情况,即把原来的对象完整的赋值到另外一地方,重新加载一内存区,一个地方变了不影响另一个地方的对象。一般用来修饰NSString等有对应可变类型的对象,因为他们有可能和对应的可变类型(NSMutableString)之间进行赋值操作,为确保对象中的字符串不被修改 ,应该在设置属性是拷贝一份。而若用strong修饰,如果对象在外部被修改了,会影响到属性。

    retain:释放旧的对象,将旧对象的值赋予输入对象,再提高输入对象的索引计数 为1

    Copy 其实是建立了一个相同的对象,而 retain 不是:

    比如一个 NSString 对象,地址为 0×1234,内容为@”qe”

    Copy 到另外一个 NSString 之 后,地址为 0×2222,内容相同,新的对象 retain 为 1, 之前的对象没有变化

    retain 到另外一个 NSString 之 后,地址相同(建立一个指针,指针拷贝),内容当然相 同,这个对象的 retain 值+1

    assign 地址还是0x1234,内容也还是“qe”。

    block属性为什么需要用copy来修饰?

    因为在MRC下,block在创建的时候,它的内存是分配在栈(stack)上的,而不是在堆(heap)上,可能被随时回收。他本身的作于域是属于创建时候的作用域,一旦在创建时候的作用域外面调用block将导致程序崩溃。通过copy可以把block拷贝(copy)到堆,保证block的声明域外使用。在ARC下写不写都行,编译器会自动对block进行copy操作。

    注意:

    ARC下的strong等同于MRC下的retain都会把对象引用计数加1

    block属性需要用copy来修饰

    同时,在ARC下,要避免block出现循环引用,经常会:__weak typedof(self) weakSelf = self;

     copy : 只用于NSString\block


    基于weak的特性,可以有[ weak singleton]的模式,即在所有使用该单例的对象释放之后,单例对象本身也会释放。   代码如下:

    + (id)sharedInstance

    {

        static __weak SingletonClass *instance;

        SingletonClass *strongInstance = instance;

        @synchronized(self) {

            if (strongInstance == nil) {

                strongInstance = [[[self class] alloc] init];

                instance = strongInstance;

            }

        }

        return strongInstance;

    }

    Controller A, B, C 都可以持有 SingletonClass 的强引用,一旦 A,B,C 都销毁后,SingletonClass 的单例对象也会随之销毁,sharedInstance中的weak就像是一个智能管家,在使用完sharedInstance之后就置为nil销毁,当sharedInstance再次被调用时,sharedInstance又会重新被创建。

    相关文章

      网友评论

          本文标题:iOS中的assign,retain,copy,weak,sto

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