2012-05-09 17 views
0

我有一个类RemoteImageLoader其中有一个方法的LoadImage:如何在Objective C中用ARC声明一个指针成员变量?

- (void) loadImage: (NSString*) url setTarget:(NSData **)target; 

我用的NSData **这里是因为我需要间接返回NSData的*,就像一些典型方法:

- (BOOL)save:(NSError**) 

自该方法将实际调用另一个异步方法,我必须将目标另存为成员变量,以便稍后可以访问它。但是当我定义的NSData **成员变量:

@interface RemoteImageLoader : NSObject  
@property NSData** target; 
@end 

编译器会抱怨说,“指向非const类型‘的NSData *’没有明确的所有权”。我在谷歌上做了一些搜索,但没有找到答案。任何人都可以帮助我吗?非常感谢

和我试图取代声明

@interface RemoteImageLoader : NSObject  
@property NSData * __autoreleasing * target; 
@end 

,但问题仍然存在

+0

[自动引用计数:指向非常量类型'NSError *'的指针没有显式所有权]的可能的重复(http://stackoverflow.com/questions/7804435/automatic-reference-counting-pointer-to-non -const型nserror与 - 无EXPL)。相同的基本逻辑。哦,并且SO也有一个搜索栏:) – CodaFi

+0

检查ARC转换文档。我相信你的情况类似于NSError。 –

+0

你不需要间接返回那个'NSData'。执行间接返回的唯一原因是您还需要_direct_返回值。当方法在失败时返回成功/失败“BOOL”或对象/“nil”时,使用'NSError **'参数技术。你的方法没有使用它的任何返回值,所以你应该只返回新的'NSData';这将使每个人的生活变得更简单(你的和客户的编码)。 –

回答

1

我不能确定你正在尝试做的,没有看到你的代码,但为什么你要创建一个指向NSData对象的指针(这是一个指向NSData的指针)。因为你正在创建一个指向这个指针的指针,这可能是你得到这个错误的原因。尝试删除其中一个指针,看看会发生什么。

+0

因为我需要间接返回NSData *,就像一些典型的方法: - (BOOL)save:(NSError **); –

1

ARC Transition Notes建议您在您的情况与__autoreleasing声明间接指针的NSData和NSError对象,如(NSData * __autoreleasing *)target;

__autoreleasing称为一生预选赛告诉编译器返回对象的自动释放的实例。

因此,需要重写您的方法签名。

- (void) loadImage: (NSString*) url setTarget:(NSData* __autoreleasing *)target; 

被警告,__autoreleasing对象是非常短暂的。将您的NSData **声明为__strong以覆盖默认的__autoreleasing以延长使用寿命。

+0

感谢@CodaFi,事实上,我已经找到了NSError *示例,并尝试了解决方案,但问题仍然存在。方法loadImage的签名对于NSData **或(NSData * __autoreleasing *)都是正确的。但是对于成员变量,都不能成功编译。 –

+0

然后声明它是强壮的。 – CodaFi

+0

这个答案解决了OP所面临的确切技术问题,代价是忽略了至少有两个原因导致什么e试图做出坏主意的事实。 –

1

我认为你的方法签名会造成麻烦。调用者很可能会认为一旦您的方法返回,指向指针就会被填充。同样,他们很可能会传递一个堆栈变量的地址,这个变量长时间不会有效。最后,你的方法没有办法让调用者知道指向指针何时填充了一个值。

你可能最好从调用者处获得一个完成块。完成块将接收一个NSData指针作为参数。喜欢的东西:

- (void) loadImage: (NSString*) url completionHandler:(void (^)(NSData* data))block; 

这也反映了底层框架API我相信你正在使用,这是一件好事减少“阻抗不匹配”。

至于你从编译器遇到的特定的狭义问题,我怀疑问题是编译器无法知道它是否应该在分配给*target时发出保留和释放。它希望你显式声明指向指针的所有权特征。我目前无法检查,但我想将它宣布为__strong NSData** target会起作用。也就是说,它对target是否拥有它指向的内容不感兴趣,因为它不能拥有指针。它对target点是否拥有它指向的NSData对象的NSData*指针感兴趣。

+0

哇,是的,不同寻常地将价值传递给参考......这是我整周听到的最糟糕的想法之一。 –

0

一般来说,当你做这样的事情ARC之外,你做这样的事情:在来电者的侧

NSData* returnedParm; 
[someObj doSomething:&returnedParm]; 

。我没有看到你的相当于我上面的returnedParm。 (我从来没有尝试过使用ARC,但我认为基本必须是类似的。)

声明属性为NSData**是声明一个指向非对象的指针,它不会被保留(因为没有保留的对象)。

我的猜测是,你应该原型的功能:

-(void)doSomething:(NSData* __autoreleasing*)theReturnParm 

,并分配给它使用*theReturnParm = something;该函数内部。

然后在呼叫方,你会有你的returnedParm作为自动发布的值(所以如果你想保留它,你应该相对快速地将它分配给strong指针)。