【问题标题】:Call an undefined method in the same thread?在同一个线程中调用未定义的方法?
【发布时间】:2014-08-22 19:22:26
【问题描述】:

我想写这样的东西:

- (int)someMethod:(SEL)theSelector {

    NSObjet *i = func(...);
    i = theSelector(i); //replace this
    i = func2(...);
    return i;
}

所以我有一些我知道并且可以简单编写的常量函数。我还有一个未定义的函数,我应该将它作为参数传递。

我不能使用像 performSelector: 这样的结构,因为它们甚至在另一个 NSRunLoop 循环中执行。

由于特定代码,我无法将块传递给此函数。

如何解决这个问题?看来objc_msgSend 可能有帮助,但我不知道如何正确使用它。

【问题讨论】:

  • 您应该重新阅读文档。 performSelector: 相当于直接调用该方法,但在您事先不知道确切选择器的情况下很有用。它不会将调用延迟到运行循环的下一次迭代。如果是这样,它就不能返回一个值,因为它是未定义的。
  • 天啊。如何将选择器作为参数传递?!我已经通过了。没看到就买眼镜。
  • 致史蒂夫·马德森,我知道performSelector: 不等同于直接调用,因为它不会在下一个代码字符串之前返回结果。还是performSelector:performSelector:...afterDelay: 不同?
  • 对 thierryb,删除你愚蠢的标记“可能重复”。如果你看不懂,请阅读以下内容。你给了我一个关于如何将一个方法传递给另一个方法的链接。但是我已经通过它并询问如何使用它。所以你的链接完全没用

标签: ios function selector param performselector


【解决方案1】:

使用 NSInvocation。 这是一个示例代码。

NSInvocation *invocation = [NSInvocation invocationWithMethodSignature: [[target class] instanceMethodSignatureForSelector:theSelector]];
[invocation setSelector:theSelector];
[invocation setTarget:target];
[invocation setArgument:&blockUserInfo atIndex:2]; // Argument 2 is the first argument in an NSInvocation, arg0 is 'self' and arg1 is '_cmd'.
[invocation invoke];
[invocation getReturnValue:&success];

希望这会有所帮助。

蒂埃里

【讨论】:

  • 抱歉,今天无法查看。是不是像我直接调用这个函数一样一次返回值?
【解决方案2】:

首先,选择器只是一个方法名。你需要一个对象来发送它。我假设它是self

在这种情况下,最简单的方法是使用performSelector:onObject:(因为它是一个接受一个对象指针参数的方法):

i = [self performSelector:theSelector withObject:i];

这与直接方法调用相同(performSelector 调用本身的开销除外)。它不会异步执行,也不会在延迟或任何事情之后执行;你很困惑。

如果你想知道怎么做,请通过objc_msgSend()

id (*func)(id, SEL, id) = (id (*)(id, SEL, id))objc_msgSend;
i = func(self, theSelector, i);

请注意,您必须首先将objc_msgSend 转换为与底层实现函数匹配的函数指针类型(开头有两个隐藏参数self;和_cmd,选择器)。这将与机器代码级别的直接方法调用完全相同。你可以想象这就是编译器编译消息调用的目的。

【讨论】:

  • 首先选择器不是方法名。先读理论。
  • @Gargo:嗯,对不起?你为什么不在喷 BS 之前先阅读你的东西?选择器是一个唯一的字符串,专门用作 Objective-C 中的方法名称。
  • 是的,它是一个唯一标识符,方法名是NSStringFromSelector(theSelector)。在数据库中,“名称”和“标识符”也有不同的含义。
  • @Gargo:在 Apple 实现中,选择器是指向以 null 结尾的 C 字符串开头的指针。在任何情况下,选择器的意义在于只有一个带有给定字符串的选择器。字符串是选择器的本质。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多