objective-c - 从 imp 调用 Objective-C 方法

标签 objective-c data-structures methods objective-c-runtime

我试图在运行时获取一个方法,然后使用它的数据结构来调用它的实现。澄清一下,这是出于学习目的,而不是出于任何实际原因。所以这是我的代码。

#import <Foundation/Foundation.h>
#import <stdio.h>

#import <objc/runtime.h>

@interface Test : NSObject 
-(void)method;
@end

@implementation Test

-(void)method {
    puts("this is a method");
}

@end 

int main(int argc, char *argv[]) {

    struct objc_method *t = (struct objc_method*) class_getInstanceMethod([Test class], @selector(method));
    Test *ztest = [Test new];

    (t->method_imp)(ztest, t->method_name);

    [ztest release];
    return 0;
}

struct objc_method的定义如下(在objc/runtime.h中定义)

typedef struct objc_method *Method;

....

struct objc_method {
    SEL method_name                                          OBJC2_UNAVAILABLE;
    char *method_types                                       OBJC2_UNAVAILABLE;
    IMP method_imp                                           OBJC2_UNAVAILABLE;
}                                                            OBJC2_UNAVAILABLE;

然而,当我尝试编译我的代码时,出现了这个错误。

错误:取消引用指向不完整类型的指针

但是当我将它添加到我的代码中(显式声明一个 objc_method)时,它会按预期工作。

struct objc_method {
    SEL method_name;
    char *method_types;
    IMP method_imp;
};

typedef struct objc_method* Method;

有人可以向我解释为什么我的代码在我显式声明此结构时有效,而在我从 objc/runtime.h 导入它时却无效吗?它与 OBJC2_UNAVAILABLE 有什么关系吗?我找不到它的定义,但它是在我的环境中定义的。

编辑:

我运行了 gcc -E code.m -o out.m 来查看 OBJC2_UNAVAILABLE 被替换了什么,事实证明 OBJC2_UNAVAILABLE 在我的环境中被定义为 __attribute__((unavailable))。有人能解释一下这意味着什么吗?如果这个结构“不可用”,为什么 Method 仍然有效?

最佳答案

我刚刚仔细查看了 objc 运行时 header ,发现了问题所在,以及如何解决它:)

因此,如果您查看包含结构透明定义的文件区域,您会发现它位于以下文件的正文中:

#if !__OBJC2__

...

#endif

由于这是定义的,这意味着我们引用的结构实际上是前向声明的和不透明的(因此是不完整的)。

我们必须做的是使用提供的函数来访问这些成员:

IMP method_getImplementation(Method method);
SEL method_getName(Method method);
void method_getReturnType(Method method, char *dst, size_t dst_len);

等等

您可以在 Runtime Reference Guide 中查看访问器方法的完整列表和大量其他好东西。 .

希望对您有所帮助!

关于objective-c - 从 imp 调用 Objective-C 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11771523/

相关文章:

ios - 用于解析 iOS 应用程序的 Facebook 登录无法正常工作

algorithm - 有效查找查询范围内整数的数据结构

python - 3D 数据的最佳数据结构?

java - 使用来自不同类的参数访问方法

c++ - 将二维数组打印为 C++ 中的方法

iphone - 选择器添加参数

iphone - 获取国家域名代码

ios - iosopendev-找不到首选项框架文件错误

java - 为什么二叉堆是树结构?

java - 不确定这个 Java 代码示例中发生了什么