iOS - 在performselector中传递引用

时间:2012-10-09 16:13:59

标签: objective-c pass-by-reference performselector

我有以下问题并无法解决,也许有人知道一招:)

主要对象必须是动态的,因为它可能是不同的......

应该调用的函数:

+ (NSArray *)parseJSONString:(NSString *)theJSONString error:(NSError **)errorPointer

正如代码已经声明的那样,我想解析JSON。我有几个实现此功能的对象,这就是我使用performSelector方法的原因:

if ([[self.theObject class] respondsToSelector:@selector(parseJSONString:error:)]) {
     NSError *parsingError = nil;
     self.myObjectsCollection = [[self.theObject class] performSelector:@selector(parseJSONString:)
                                                             withObject:utf8ResponseString
                                                             withObject:parsingError];        
}

utf8ResponseString包含JSON ...

我已经尝试了以下内容:

... withObject:&parsingError -> compile error
... withObject:[NSValue valueWithPointer:&parsingError] -> works until the value will be redirect to the parsingError -> Bad Exec

我已经搜索了一天,甚至没有找到如何解决这个问题 - 请帮忙...

谢谢和问候, 马修

3 个答案:

答案 0 :(得分:4)

要添加其他答案的完整性,如果你真的需要动态调用一个名称只在运行时知道的方法(事实证明你不需要在这种情况下,但如果你这样做)对象参数,然后正确的解决方案是:

  • 使用NSInvocation或
  • 直接调用其中一个objc_msgSend...运行时函数

答案 1 :(得分:2)

performSelector:...方法系列只接受对象参数。您希望将指针传递给指针,该指针与对象不同,因此类型系统不允许它。幸运的是,你根本不需要performSelector:。你可以[[self.theObject class] parseJSONString:utf8ResponseString error:&parsingError]

只有在运行时才知道要发送的消息时,才需要使用performSelector:。如果您没有将变量作为第一个参数传入,则可能不需要它。

但是,如果您确实需要这样做,那么您需要做的是编写一个“包装器”方法,该方法接受一个对象(例如,NSValue)并使用非对象类型调用实际方法,并且你用performSelector:withObject:调用包装器而不是真正的方法。

答案 2 :(得分:1)

为什么不直接打电话给班上的方法呢?您已经检查过它可以响应该方法。所以直接调用该方法。

[[self.theObject class] parseJSONString: nil error: &error].

顺便说一句,你可以做一个简单的状态模式交换。即使在运行时定义了对象响应器,消息调用也不是。如果编译器警告您,则转义为id。因为我不确定你可以在类方法上分配协议。 (但也许你可以)。

您甚至可以将所有对象解析器嵌入到代理解析器类中,以便在编译时定义它。

可以肯定的是,您可以将指针对象(** erorr)传递给performSelector ::(因为运行时不是预言者)。如果你真的需要,做一个简单的c函数callBack?