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 

  • 相关阅读:
    POJ 3261 Milk Patterns (求可重叠的k次最长重复子串)
    UVaLive 5031 Graph and Queries (Treap)
    Uva 11996 Jewel Magic (Splay)
    HYSBZ
    POJ 3580 SuperMemo (Splay 区间更新、翻转、循环右移,插入,删除,查询)
    HDU 1890 Robotic Sort (Splay 区间翻转)
    【转】ACM中java的使用
    HDU 4267 A Simple Problem with Integers (树状数组)
    POJ 1195 Mobile phones (二维树状数组)
    HDU 4417 Super Mario (树状数组/线段树)
  • 原文地址:https://www.cnblogs.com/feng9exe/p/10383633.html
Copyright © 2011-2022 走看看