假设对象A 具有属性:
@property (nonatomic, strong) Foo * bar;
在实现中合成为:
@synthesize bar = _bar;
对象B 操纵Foo **
,如本例中对象A 的调用:
Foo * temp = self.bar;
[objB doSomething:&temp];
self.bar = temp;
doSomething:
方法的正确声明是什么?此外,假设在我有机会设置bar
属性之前可以取消分配对象B (从而取得temp
指向的实例的所有权) - 我如何告诉ARC交出拥有的参考资料?换句话说,如果我想让以下示例代码段起作用,我将如何处理ARC问题?
Foo * temp = self.bar; // Give it a reference to some current value
[objB doSomething:&temp]; // Let it modify the reference
self.bar = nil; // Basically release whatever we have
_bar = temp; // Since we're getting back an owning reference, bypass setter
修改
根据@KevinBallard的回答,我只想证实我的理解。这是对的吗?
对象A:
@implementation ObjectA
@synthesize bar = _bar;
- (void)someMethod
{
ObjectB * objB = [[ObjectB alloc] initWithFoo:&_bar];
// objB handed off somewhere and eventually it's "doSomething" method is called.
}
@end
对象B:
@implementation ObjectB
{
Foo * __autoreleasing * _temp;
}
- (id)initWithFoo:(Foo * __autoreleasing *)temp
{
id self = [super init];
if (self)
{
_temp = temp;
}
return self;
}
- (void)doSomething
{
...
*_temp = [[Foo alloc] init];
...
}
@end
这会产生编译时错误:passing address of non-local object to __autoreleasing parameter for write-back
答案 0 :(得分:6)
这是完全合法的。物业访问无关紧要;将指针传递给对象通常使用NSError*
个对象。
声明方法的正确方法是
- (returntype)doSomething:(Foo * __autoreleasing *)arg;
这将它声明为指向__autoreleasing
对象的指针,这基本上意味着被指向的对象被认为是-autorelease
d。
至于“此外”,这不是ARC的问题。你的行
Foo * temp = self.bar;
相当于
__strong Foo *temp = self.bar;
我希望你明白这会使temp
成为一个强引用,因此只要变量存在,它就“拥有”它的值。换句话说,你可以说
Foo *temp = self.bar;
self.bar = nil;
且temp
仍然有效。