在代码片段示例中使用__autoreleasing
以下代码摘自“iOS 5 Developer's Cookbook”,用于说明如何将string写入文件。 它利用__autoreleasing没有任何解释。 为什么有必要?
NSError __autoreleasing error; ... if (![myString writeToFile:path atomically:YES error:&error) { NSLog(.... error.localizedFailureReason ...); return; }
为什么不直接声明栈上的错误而不使用__autoreleasing?
——编辑—–
附加问题:为什么作者声明NSError而不是NSError *?
这是自动引用计数(ARC)系统的一个提示。
error
对象将被分配在NSString代码的某处,所以在你的代码中声明它为__autoreleasing
让ARC知道存储特性是什么。 也就是说,当error
被设置时,它将是一个自动释放的对象。
当一个variables通过引用传递并分配给一个ARC程序时,你错过了这段代码中实际发生的事情。 以一个函数(BOOL)保存为例:(NSError * __autoreleasing *)错误
在非ARC编程中,保存function如下所示:
- (BOOL)save:(NSError * __autoreleasing *)myError { *myError = [[[NSError error] retain] autorelease] }
在ARC编程中,保存function如下所示:
- (BOOL)save:(NSError * __autoreleasing *)myError { *myError = [[NSError alloc] init]; }
尽pipeARC代码看起来像,两个保存函数都会创build一个已被保留和自动释放的错误对象。
这是因为在ARC版本中,myError指针的types决定了错误对象的内存pipe理会发生什么情况。 实际上,只要指针的types是__autoreleasing,* myError赋值行就被replace成了
*myError = [[[NSError error] retain] autorelease]
在运行时。
所以如果我们不知何故能够传入一个错误types的指针,例如__strong到保存函数,它会导致保存function做错误的事情。
由于编译器会通过创build一个临时variables来防止这种情况的发生,代码将以任何方式工作,但传递一个非__autoreleasingtypes的指针从ARC编程的angular度来看是没有意义的。
从ARC发行说明: https : //developer.apple.com/library/ios/#releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html :
__autoreleasing用于表示通过引用(id *)传递的参数,并在返回时自动释放。
在声明variables的时候有一个隐含的__strong声明,但是由于它是通过引用传递的,所以编译器需要提示才能做正确的事情。 它是否是堆栈variables不会影响保留/释放跟踪。
代码 :
__autoreleasing NSString *str = xx;
将由ARC编译为:
NSString *str = xx.autorelease
那么,对于通过引用传递的对象,使用__autoreleasing限定符是一个ARC约定。 这个解释来自clang站点:
4.3.2。 __autoreleasing对象的存储时间
如果一个程序声明了一个非自动存储持续时间的__autoreleasing对象,那么这个程序是不合格的。
理由:autorelease池被绑定到当前线程和范围的性质。 虽然有可能拥有实例variables被自动释放对象填充的临时对象,但是ARC没有办法在那里提供任何安全保证。
这是未定义的行为,如果一个非空指针分配给__autoreleasing对象,而autorelease池在范围内,然后该对象是在autorelease池的范围留下后读取。
- 快速添加手势到button
- UIScrollView在addSubview或更改框架之后不需要的滚动
- 在App Store中接受哪些iOs版本的应用程序
- Xcode表示,当我导入本地化时,Infoplist.strings已经存在
- 缺less必需的图标文件。 该捆绑包不包含完全为'57×57'像素的iPhone / iPod Touch的应用程序图标
- 具有多边形的SCNGeometry作为primitiveType
- 无法更改视图中绘制的圆的颜色
- 由于Facebook SDK和Flurry SDK中的advertisingIdentifier而被拒绝的应用程序
- AFNetworking 2.0如何在POST请求的查询string中添加一些参数