zoukankan      html  css  js  c++  java
  • ARC下的所有权修饰符

    ARC有效时,id类型必须加上所有权修饰符

    • 下面为三种等效的声明,为了便于和二级指针的情况联系起来,采用第一种。
     NSError * __weak error = nil;
     NSError __weak  *error = nil;
     __weak NSError *error = @"hehe";
    

    所有权修饰符

    __strong

    • 默认修饰符,修饰的变量的默认值为nil。当需要释放强引用指向的对象时,需要将强引用置nil。
    • 持有强引用的变量在超出其作用域时被废弃,同时释放其引用的对象

    __weak

    • 弱引用不增加对象的引用计数,不能持有对象实例
      • 下列程序会引起编译警告。更好的做法是将强引用赋给弱引用
    id __weak = [[NSObject alloc] init];
    
    • 对象在被dealloc时,指向它的弱引用会自动被置nil(zeroing weak pointer),防止野指针产生
    • 弱引用一般用于处理retain cycle,如在delegate关系中防止循环引用或者用来修饰指向由Interface Builder编辑生成的UI控件

    __unsafe_unretained

    • __unsafe_unretained修饰的变量不属于编译器的内存管理对象,可理解为MRC时代的assign
    • 不增加所引用对象的引用计数值,但是不保证指针指向的可访问性(类似于C++的普通指针,存在野指针情况)

    __autoreleasing

    • ARC有效时,使用@autoreleasepool块代替NSAutorelesePool类,用附有__autoreleasing修饰的变量替代autorelease方法
    • 主要用在参数传递返回值(out-parameters)和引用传递参数(pass-by-reference)的情况下。
    • 此类对象在创建出来后,被注册到autoreleasing pool中
    • __autoreleasing修饰的变量要为自动变量(局部变量,函数以及方法参数)

    二级指针与修饰符

    • 二级指针(id的指针或对象指针的指针)在没有显示指定时会被附加上__autoreleasing修饰符

      • NSError *error等价于NSError * __strong error
      • NSError ** error等价于NSError * __autoreleasing *error
      • 实际上,现在xcode中已经不允许不带修饰符的二级指针 屏幕快照 2016-08-04 下午6.39.53
    • 给二级指针的解引用赋值时,应保证两边的修饰符相同

      • 错误示例
        屏幕快照 2016-08-04 下午6.44.14

      • 正确示例

       NSError* __autoreleasing error = nil;
       NSError* __autoreleasing *p_error = &error;
    
    • 在调用形参为二级指针的方法时,如果用户传入实参的所有权修饰符不符,编译器会转换源代码
      • 原代码
    - (void)getError:(NSError* __autoreleasing *)error {
        error = nil;
    }
    - (void)callGetError {
        NSError *error = nil;
        [self getError:&error];
    }
    
    
    • 转换后的callGetError
    - (void)callGetError {
        NSError *error = nil;
         NSError* __autoreleasing tmp = error;
        [self getError:&tmp];
        error = tmp;
    }
    

    二级指针与__autoreleasing

    • 当函数形参arg为__autoreleasing修饰的二级指针时,在函数体内对*arg赋值,最终*arg引用的是已注册到autoreleasepool的对象
    void getErr:(NSError * __autoreleasing *)error {
        *error = [[NSError alloc] initWithDomain:aDomain code:NSURLErrorBadURL userInfo:nil];
    }
    
  • 相关阅读:
    docker4dotnet #1 – 前世今生 & 世界你好
    DockerCon 2016 – 微软带来了什么?
    TFS 2015 敏捷开发实践 – 看板的使用
    几款Git GUI客户端工具
    (视频)Erich Gamma 与 Visual Studio Online 的一点野史
    GitHub + VSTS 开源代码双向同步
    UDAD 用户故事驱动的敏捷开发 – 演讲实录
    用户故事驱动的敏捷开发 – 2. 创建backlog
    算法 之 简单选择排序法
    算法 之 冒泡排序法
  • 原文地址:https://www.cnblogs.com/rainySue/p/ARC-xia-de-suo-you-quan-xiu-shi-fu.html
Copyright © 2011-2022 走看看