zoukankan      html  css  js  c++  java
  • autoreleasing的用法介绍:



      在c/c++,objective-c内存管理中有一条是:谁分配谁释放。 __autoreleasing则可以使对像延迟释放。比如你想传一个未初始化地对像引用到一个方法当中,在此方法中实始化此对像,那么这种情况将是__autoreleasing表演的时候。看个示例:
      
    1. - (void) generateErrorInVariable:(__autoreleasing NSError **)paramError{ NSArray *objects = [[NSArray alloc] initWithObjects:@"A simple error", nil]; NSArray *keys = [[NSArray alloc] initWithObjects:NSLocalizedDescriptionKey, nil]; NSDictionary *errorDictionary = [[NSDictionary alloc] initWithObjects:objects forKeys:keys]; *paramError = [[NSError alloc] initWithDomain:@"MyApp" code:1 userInfo:errorDictionary]; } -(void)test { NSError *error = nil; [self generateErrorInVariable:&error]; NSLog(@"Error = %@", error); }
    复制代码

      被编译器翻译后就变为:

    1.   -(void)test { NSError *error = nil; NSError * __autoreleasing tmp = error; [self generateErrorInVariable:&tmp]; error = tmp; NSLog(@"Error = %@", error); }
    复制代码

      这样即便在函数内部申请的空间,在函数外部也可以使用,同样也适合谁分配谁释放的原则。

      同样下面的代码也是类似原因, 只不过在没有开启ARC的情况下适用:
      
    1. -(NSString *)stringTest { NSString *retStr = [NSString stringWithString:@"test"]; return [[retStr retain] autorelease]; }
    复制代码

      开启ARC后,应改为:经过测试下面这种方法是可行的,不过都不建意这样写代码, __autoreleasing官网的例子是用在传引用参数当中(像上面那个NSError)。所以最好不要像下面这样用
     
    1.  -(NSString *)stringTest { __autoreleasing NSString *retStr = [NSString alloc] initWithString:@"test"]; return retStr; }
    2.   - (NSString *)stringTest __attribute__((ns_returns_autoreleased)){ NSString *retStr = [NSString alloc] initWithString:@"test"];return retStr;}
    复制代码

      与上面功能相似。返回一个autorelease。

      关于methord family, 如果方法名是以alloc, init, copy, mutablecopy,new字符开头的,那么它们的返回值会被retain的,其它的默认就是autorelease返回的。下面介绍一下返回值的例子:
     
    1.  - (id) foo __attribute((ns_returns_retained)); //返回值retain +1, init,new,alloc,copy,mutablecopy default are this - (id) foo __attribute((ns_returns_not_retained)); //返回指针弱引用, - (id) foo __attribute((ns_returns_autoreleased)); //返回autorlease, except default, are this
    复制代码

      init开头的方法有一个规定,一定要返回id或父类,子类的指针,不然要有warning.

      这儿是原话:
     
    1.  init methods must be instance methods and must return an Objective-C pointer type. Additionally, a program is ill-formed if it declares or contains a call to an init method whose return type is neither id nor a pointer to a super-class or sub-class of the declaring class (if the method was declared on a class) or the static receiver type of the call (if it was declared on a protocol).
    复制代码

      当然你也可以打破这个规定,如果你这样声明方法:
      
    1. - (void)initStr __attribute__((objc_method_family(none)));
    复制代码

      那么就是正确的。
  • 相关阅读:
    【AppScan心得】IBM Rational AppScan 无法记录登录序列
    tomcat记录XForwardedFor字段中的远程IP
    【AppScan深入浅出】修复漏洞:会话标识未更新(中危)
    用java在Windows控制台输出utf8字符
    【图解漏洞】图解跨站脚本攻击(XSS)原理
    【图解漏洞】图解跨站请求伪造(CSRF)原理(之二)
    雅克比矩阵(Jacobian Matrix)在正运动学中的应用
    游戏物理引擎之静态碰撞
    万向节死锁(Gimbal Lock)
    旋转矩阵(Rotate Matrix)的性质分析
  • 原文地址:https://www.cnblogs.com/zsw-1993/p/4879685.html
Copyright © 2011-2022 走看看