4

我知道可以使用 objc_msgSend 来使用 Objective C 代码,我相信,手动运行 Objective C 运行时但是当我运行此代码时,我收到引用 NSString 的错误(即使我从未使用它)以及其他未使用的类.

来自 xcode 的错误

在此处输入图像描述

我在它上面有我试图“模仿”的目标 C 代码(注释掉)。

#include <Foundation/Foundation.h> /*Added suggestion by answer, same errors*/
#include <AppKit/AppKit.h>

int main()
{
// convert objective c into c code
/*
    NSAlert *alert = [[NSAlert alloc] init];
    [alert setAlertStyle:NSInformationalAlertStyle];
    [alert setMessageText:@"Hello World"];
    [alert setInformativeText:@"Hello World"];
    [alert runModal];
*/
    id alert = objc_msgSend(objc_msgSend(objc_getClass("NSAlert"), sel_registerName("alloc")), sel_registerName("init"));
    objc_msgSend(alert, sel_getUid("setAlertStyle:"), NSInformationalAlertStyle);
    objc_msgSend(alert, sel_getUid("setMessageText:"), CFSTR("Hello World!"));
    objc_msgSend(alert, sel_getUid("setInformativeText:"), CFSTR("Hello World!"));
    objc_msgSend(alert, sel_getUid("runModal"));
}
4

1 回答 1

5

你错过了一些进口。

objc_msgSend在中声明<objc/message.h>

objc_getClass在中声明<objc/runtime.h>

sel_getUidsel_registerName<objc/objc.h>.

现在,鉴于<objc/objc.h>已经由<objc/runtime.h>导入,将后者与<objc/message.h> 一起导入就足够了。

我用以下示例对其进行了测试,它按预期工作

#include <CoreFoundation/CoreFoundation.h> // Needed for CFSTR
#include <objc/runtime.h>
#include <objc/message.h>

int main(int argc, char *argv[]) {
    id alert = (id (*)(id, SEL))objc_msgSend((id (*)(id, SEL))objc_msgSend(objc_getClass("NSAlert"), sel_registerName("alloc")), sel_registerName("init"));
    (void (*)(id, SEL, int))objc_msgSend(alert, sel_getUid("setAlertStyle:"), 1); // NSInformationalAlertStyle is defined in AppKit, so let's just use 1
    (void (*)(id, SEL, id))objc_msgSend(alert, sel_getUid("setMessageText:"), CFSTR("Hello World!"));
    (void (*)(id, SEL, id))objc_msgSend(alert, sel_getUid("setInformativeText:"), CFSTR("Hello World!"));
    (int (*)(id, SEL))objc_msgSend(alert, sel_getUid("runModal"));
}

笔记

objc_msgSend我按照 Greg Parker 在评论中的建议添加了明确的演员表。

于 2013-09-08T22:38:27.397 回答