处理ARC中的指针到指针所有权问题

时间:2012-01-11 05:42:55

标签: objective-c automatic-ref-counting

假设对象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

1 个答案:

答案 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仍然有效。