【问题标题】:Using method_getReturnType to call specific types of instance member functions使用method_getReturnType调用特定类型的实例成员函数
【发布时间】:2019-02-16 00:35:33
【问题描述】:

我是 Objective-C 的新手,所以我对这门语言不太了解。

我要做的是遍历对象的所有可用实例方法,并调用不带参数的方法,返回 bool 并以字符串“func”开头。

我是这样获取方法的:

uint32_t methodCount = 0;
Method * methods = class_copyMethodList(object_getClass(self), &methodCount);

我遍历方法,当上述条件匹配时,尝试调用它们:

NSString * methodName   = [NSString stringWithUTF8String:sel_getName(method_getName(method))];

char retTyp[10];
method_getReturnType(method, retTyp, 10);

const char * desiredRetType = "B";

if([methodName hasPrefix:@"func"] &&
   (0 == strncmp(retTyp, desiredRetType, strlen(desiredRetType))) &&
   (2 == method_getNumberOfArguments(method)))
{
     bool * (* testMethod) (id, Method) = (void (*) (id, Method, ...)) method_invoke;
     result = testMethod(self, method);
}

我必须通过实验弄清楚返回类型字符串是什么(结果是“B”代表布尔值),以及参数的数量。

我在尝试使用 method_invoke 调用函数的那一行遇到以下错误:

cannot initialize a variable of type 'bool *(*)(__strong id, Method)' (aka 'bool *(*)(__strong id, objc_method *)') with an rvalue of type 'void (*)(__strong id, Method, ...)' (aka 'void (*)(__strong id, objc_method *, ...)'): different return type ('bool *' vs 'void') 
  1. 有没有比 class_copyMethodList 更好的方法来做到这一点?
  2. 如何正确转换函数以免出错?
  3. 是否有可能将method_getReturnType()转换为return 类型可能会因系统而异?还是总是 B 代表 bool?

【问题讨论】:

  • method_invoke 是从哪里来的?
  • 在 3 上,技术上是的,但实际上没有。
  • method_invoke 来自Apple。至于3,能详细点吗?
  • 当然。编码由编译器定义:stackoverflow.com/questionsS/11527385,但它们也被运行时使用。所以他们需要同步。因此,您可以拥有一个将它们定义为 whatever 的编译器/运行时对,但在该对上运行的程序将与任何其他运行时不兼容。所以目前的编码有点像ipso facto ABI。

标签: objective-c objective-c-runtime


【解决方案1】:

NVM,我想通了。我没有在方法名称上使用 method_invoke,而是这样做了:

NSString * methodName   = [NSString stringWithUTF8String:sel_getName(method_getName(method))];

char retTyp[10];

method_getReturnType(method, retTyp, 10);
const char * desiredRetType = "B";

if([methodName hasPrefix:@"func"] &&
   (0 == strncmp(retTyp, desiredRetType, strlen(desiredRetType))) &&
   (2 == method_getNumberOfArguments(method)))
{
    SEL testMethod = method_getName(method);
    return [self performSelector:testMethod];
}

【讨论】:

  • 这仍然是错误的。您应该使用 method_getImplementation(),并转换该函数指针的结果以安全地调用该方法。 -performSelector: 是 U.B.如果函数的签名不是-(id) func,在您的情况下似乎返回BOOL。它可能会起作用,但可能会导致问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-17
相关资源
最近更新 更多