__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]方法释放内存池。

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

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

__autoreleasing 与 局部变量的更多相关文章

  1. 一道题考你对__autoreleasing和__block的理解

    考虑下面的代码,有哪些问题,如何把他改成正确的形式? @interface TestObj : NSObject @end @implementation TestObj - (void)method ...

  2. 针对JS经典题型对全局变量及局部变量的理解浅谈

    第一次写博,还蛮激动... 看到了三题经典题型,就我目前的认识对此题进行总结.如有错误,敬请指正 首先,我们先明确一下JS引擎的工作步骤: js引擎工作分为两步: 1.将这个js中的变量和函数声明保存 ...

  3. Python 局部变量与全局变量

    本来以为 局部变量就是在函数/def/class/lambda内部的变量,全局变量就是在之前这些之外的变量.但是,再一次学习Python atm 中应用时发现了一次特例(意外) 字典中 在函数内部改变 ...

  4. iOS 局部变量 全局变量 成员变量

    一.成员变量 : 写在类声明的大括号中的变量叫成员变量 (也叫属性/实例变量) 成员变量不可离开类 离开了类就不是成员变量 成员变量不能再定义的同事初始化 成员量只能通过对象来访问 成员变量存储在堆中 ...

  5. [Sass]局部变量和全局变量

    [Sass]局部变量和全局变量 Sass 中变量的作用域在过去几年已经发生了一些改变.直到最近,规则集和其他范围内声明变量的作用域才默认为本地.如果已经存在同名的全局变量,从 3.4 版本开始,Sas ...

  6. js方法入参或局部变量和全局变量重名,用来赋值全局变量会失败

    今天遇到个bug,最后终于知道原因了,js方法入参和全局变量重名,用入参赋值全局变量失败,就是说方法入参不能和全局变量重名. 现在下面的例子也说明,局部变量和全局变量不可以同名不光是入参,只要同名赋值 ...

  7. JS函数 -- 功能,语法,返回值,匿名函数,自调用匿名函数,全局变量与局部变量,arguments的使用

    “JavaScript设计得最出色的就是它的函数的实现.” -- <JavaScript语言精粹> 函数包含一组语句,它们是JS的基础模块单元,用于指定对象的行为.一般来说,所谓编程,就是 ...

  8. Java易混淆的概率:成员变量、类变量、实例变量、局部变量

    先看代码 public class Variable{ int b=0; //实例变量 static int a=0; //类变量 final String c="wws"; // ...

  9. JavaScript的全局变量与局部变量解析

    一.JavaScript scope 的划分标准是function函数块,不是以 if.while.for来划分的 <script> function f1(){ alert(" ...

随机推荐

  1. [HTML5] Canvas绘制简单图片

    获取Image对象,new出来 定义Image对象的src属性,参数:图片路径 定义Image对象的onload方法,调用context对象的drawImage()方法,参数:Image对象,x坐标, ...

  2. 使用tcmalloc替换系统的malloc

    https://blog.csdn.net/educast/article/details/79166553?utm_source=blogxgwz0 今天对服务器进行压测,模拟的请求量到4万次/分的 ...

  3. 深入理解JVM之JVM内存区域与内存分配

    深入理解JVM之JVM内存区域与内存分配 在学习jvm的内存分配的时候,看到的这篇博客,该博客对jvm的内存分配总结的很好,同时也利用jvm的内存模型解释了java程序中有关参数传递的问题. 博客出处 ...

  4. Java向数据库中一次性插入大量数据

    String sql = “insert into username.tablename(id) values(?)”; PreparedStatement stmt = conn.prepareSt ...

  5. EF_CRUD

  6. 使用IntelliJ IDEA配置Erlang开发环境

    这篇文章比较详细,感谢作者,拷贝过来做个记录 ————————————————————————————————————————————————————————————————————————————— ...

  7. 献给java求职路上的你们

    为了更好的树立知识体系,我附加了相关的思维导图,分为pdf版和mindnote版.比如java相关的导图如下: 由于时间仓促,有些地方未写完,后面会继续补充.如有不妥之处,欢迎及时与我沟通. 相关概念 ...

  8. cookie implements session

    cookie实现会话 服务器调用response.addCookie()设置set-cookie响应头后,浏览器收到这个响应头与数值后,会将它以文件的形式存储于本地PC上.当浏览器再次访问同一Web服 ...

  9. UnicodeEncodeError: 'ascii' codec can't encode characters in position 2-5: ordin al not in range(128)——解决方案备注

    在vim中使用ycm插件时,偶尔会出现: “UnicodeEncodeError: 'ascii' codec can't encode characters in position 2-5: ord ...

  10. angularjs初识ng-app、ng-model、ng-repeat指令

    ng-app属性是angular.js的标志语句,它标记了angular.js的作用域.ng-app可以添加在很多地方,像上面那样添加到html标签上,说明angular脚本对整个页面都起作用.也可以 ...