1

我有以下问题,无法解决,也许有人知道一个窍门:)

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

应该调用的函数:

+ (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

我已经搜索了一天,甚至不知道如何解决这个问题-请帮助...

谢谢和问候,马修

4

3 回答 3

4

为了增加完整性的其他答案,如果您确实需要使用非对象参数动态调用名称仅在运行时知道的方法(事实证明在这种情况下您不需要,但如果您这样做了),那么正确的解决方案是:

  • 使用 NSInvocation,或
  • 直接调用其中一个objc_msgSend...运行时函数
于 2012-10-10T00:37:13.647 回答
2

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

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

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

于 2012-10-09T16:39:53.940 回答
1

为什么不直接调用类上的方法呢?您已经检查过它是否可以响应该方法。所以直接调用方法。

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

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

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

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

于 2012-10-09T16:40:51.463 回答