zoukankan      html  css  js  c++  java
  • __autoreleasing 与 局部变量

    __autoreleasing 修饰的变量不是局部变量;

    它的生命周期由autoreleasepool负责;

    +(Reachability*)reachabilityWithHostname:(NSString*)hostname

    {

        SCNetworkReachabilityRef ref = SCNetworkReachabilityCreateWithName(NULL, [hostname UTF8String]);

        if (ref) 

        {

            id reachability = [[self alloc] initWithReachabilityRef:ref];

            return [reachability autorelease];

        }

        

        return nil;

    }

    局部变量由编译器插入的内存管理负责;只在作用域内有效,在步出作用域时会释放;

    局部变量是强引用。

    强引用的释放:

    1、对象的析构释放;

    2、作用域管理;

    __autoreleasing

    表示在autorelease pool中自动释放对象的引用,和MRC时代autorelease的用法相同。定义property时不能使用这个修饰符,任何一个对象的property都不应该是autorelease型的。

    一个常见的误解是,在ARC中没有autorelease,因为这样一个“自动释放”看起来好像有点多余。这个误解可能源自于将ARC的“自动”和autorelease“自动”的混淆。其实你只要看一下每个iOS App的main.m文件就能知道,autorelease不仅好好的存在着,并且变得更fashion了:不需要再手工被创建,也不需要再显式得调用[drain]方法释放内存池。

    311645216448780.png

    以下两行代码的意义是相同的。

    NSString *str = [[[NSString alloc] initWithFormat:@"hehe"] autorelease]; // MRC

    @"hehe"// ARC

     这里关于autoreleasepool就不做展开了,详细地信息可以参考官方文档或者其他文章。

    在中主要用在参数传递返回值()和引用传递参数()的情况下。

    __autoreleasing is used to denote arguments that are passed by reference (id *) and are autoreleased on return.

    比如常用的NSError的使用:

    NSError *__autoreleasing error; 

    (![data writeToFile:filename options:NSDataWritingAtomic error:&error]) 

      @"Error: %@", error); 

    (在上面的writeToFile方法中error参数的类型为(NSError *__autoreleasing *))

    errorstrong__autoreleasing

    NSError *error; 

    // 编译器添加 

    (![data writeToFile:filename options:NSDataWritingAtomic error:&tempError]) 

      // 编译器添加 

      @"Error: %@", error); 

    所以为了提高效率,避免这种情况,我们一般在定义error的时候将其(老老实实地=。=)声明为__autoreleasing类型的:

    NSError *__autoreleasing error;

    在这里,加上__autoreleasing之后,相当于在MRC中对返回值error做了如下事情:

    *error = [[[NSError alloc] init] autorelease];

    *error指向的对象在创建出来后,被放入到了autoreleasing pool中,等待使用结束后的自动释放,函数外error的使用者并不需要关心*error指向对象的释放。

    ARC NSError **__autoreleasing比如下面的两段代码是等同的:

    - (NSString *)doSomething:(NSNumber **)value

    {

            // do something  

    - (NSString *)doSomething:(NSNumber * __autoreleasing *)value

    {

            // do something  

    除非你显式得给value声明了__strong,否则value默认就是__autoreleasing的。

    autorelease pool__autoreleasing比如NSDictionary的[enumerateKeysAndObjectsUsingBlock]方法:

    - (void)loopThroughDictionary:(NSDictionary *)dict error:(NSError **)error

    {

        [dict enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop){

              // do stuff  

              if (there is some error && error != nil)

              {

                    *error = [NSError errorWithDomain:@"MyError" code:1 userInfo:nil];

              }

        }];

    会隐式地创建一个autorelease pool,上面代码实际类似于:

    - (void)loopThroughDictionary:(NSDictionary *)dict error:(NSError **)error

    {

        [dict enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop){

    @autoreleasepool  // 被隐式创建

          {

                  if (there is some error && error != nil)

                  {

                        *error = [NSError errorWithDomain:@"MyError" code:1 userInfo:nil];

                  }

                  }];

        // *error 在这里已经被dict的做枚举遍历时创建的autorelease pool释放掉了 :(  

    }    

    为了能够正常的使用*error,我们需要一个strong型的临时引用,在dict的枚举Block中是用这个临时引用,保证引用指向的对象不会在出了dict的枚举Block后被释放,正确的方式如下:

    - (void)loopThroughDictionary:(NSDictionary *)dict error:(NSError **)error

      // 加保证可以在内被修改  

      idid  { 

         (there some error) 

          @"MyError"1 

    }  

      }] 

       (error != nil) 

      { 

        *error = tempError; 

      } 

    http://www.cnblogs.com/flyFreeZn/p/4264220.html 

  • 相关阅读:
    小程序开发为何使用RPX
    C#判断网址是否可以访问
    [golang]go语言的channel学习
    tensorflow中图像增强的方法详解
    kaggle无法下载数据集解决办法
    keras模型中的model.fit()和model.fit_generator()的区别
    Keras.metrics中的accuracy总结
    Python 字符串前面加u,r,b,f的含义
    损失函数:binary_crossentropy、categorical_crossentropy、sparse_categorical_crossentropy
    jupyter代码自动补全
  • 原文地址:https://www.cnblogs.com/feng9exe/p/10383633.html
Copyright © 2011-2022 走看看