__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. Springboot --- Spring Security (一)

      文章部分图片来自参考资料 问题 : Spring Security 内部实现的原理是什么 概述 Spring Security 是个安全框架,可以提供认证,防止网络功能等功能,可以结合 sprin ...

  2. 双11抢券,写一个自动打开页面的html,仅仅是设定时间打开抢券的页面

    <!DOCTYPE html> <html lang="en" xmlns="http://www.w3.org/1999/xhtml"> ...

  3. java 对CSV 文件的读取与生成

    CSV文件是以逗号分隔值的文件格式,一般用WORDPAD或记事本(NOTE),EXCEL打开.CSV(逗号分隔值)是一种用来存储数据的纯文本文件,通常都是用于存放电子表格或数据的一种文件格式,对于CS ...

  4. 1.1 JAVA装箱和拆箱以及Java Number & Math&Character 类

    JAVA装箱和拆箱 从Java SE5开始就提供了自动装箱的特性,如果要生成一个数值为10的Integer对象,只需要这样就可以了.原文链接: http://www.cnblogs.com/dolph ...

  5. MySQL内连接和外连接

    INNER JOIN(内连接,或等值连接):获取两个表中字段匹配关系的记录. LEFT JOIN(左连接):获取左表所有记录,即使右表没有对应匹配的记录. RIGHT JOIN(右连接): 与 LEF ...

  6. Python 2 和 Python 3 有哪些主要区别

    概述# 原稿地址:使用 2to3 将代码移植到 Python 3 几乎所有的Python 2程序都需要一些修改才能正常地运行在Python 3的环境下.为了简化这个转换过程,Python 3自带了一个 ...

  7. CSS-带尖角的对话框

    效果图: box1的代码: .box{ position: relative; width: 200px; height: 200px; border: 2px solid #000; backgro ...

  8. null的专栏:https://blog.csdn.net/google19890102

    null的专栏:https://blog.csdn.net/google19890102 csdn博客专栏:https://blog.csdn.net/column.html

  9. 在 Azure 中的 Linux VM 上创建 MongoDB、Express、AngularJS 和 Node.js (MEAN) 堆栈

    本教程介绍如何在 Azure 中的 Linux VM 上实现 MongoDB.Express.AngularJS 和 Node.js (MEAN) 堆栈. 通过创建的 MEAN 堆栈,可以在数据库中添 ...

  10. [翻译] GoogleMaterialDesignIcons

    GoogleMaterialDesignIcons Google Material Design Icons Font for iOS GMD图片样式的字体,用于iOS开发. It is based ...