我今天更新了 Scripting Bridge 粘合文件(用于 Mail.app),并注意到 sdp(1) 手册页 内容如下:
不需要创建对应的实现文件;脚本桥将创建 运行时的类实现。
这听起来很酷,但没有实现我得到的生成类(如预期):
Undefined symbols for architecture x86_64:
"_OBJC_CLASS_$_MailApplication", referenced from:
objc-class-ref in DMBugReportWindowController.o
"_OBJC_CLASS_$_MailAttachment", referenced from:
objc-class-ref in DMBugReportWindowController.o
[... more of the same ...]
ld: symbol(s) not found for architecture x86_64`
我不想抑制所有未定义的符号,因为这很容易掩盖合法问题,所以我只是使用
-U
(根据ld(1)手册页):
指定symbol_name没有定义也可以。和 -two_levelnamespace,生成的符号将被标记为dynamic_lookup 这意味着 dyld 将搜索所有加载的图像。
(我必须使用
-Xlinker -U -Xlinker _OBJC_CLASS_$_MailApplication
来让这些标志到达 ld,否则 clang 会保留这些参数。)
显然制作它们
dynamic_lookup
是错误的做法,因为这会在启动时出现动态链接错误:
dyld: Symbol not found: _OBJC_CLASS_$_MailApplication
Referenced from: /Users/jonathon/Library/Developer/Xcode/...
Expected in: flat namespace
in /Users/jonathon/Library/Developer/Xcode/...
如果我使用
-force_flat_namespace -undefined suppress
(我不想使用,如上所述),也会发生这种情况。 脚本桥编程指南似乎暗示我正在正确地做事(“准备编码”部分),但没有提到这个问题。
由于该类是动态创建的,因此您无法链接到它。该类将在运行时注册,但不会导出任何符号,链接器将无法找到它。
您需要将发送至
MailApplication
和 MailAttachment
的所有消息替换为发送至 NSClassFromString(@"MailApplication")
和 NSClassFromString(@"MailAttachment")
的消息。
[MailApplication class]
变为 NSClassFromString(@"MailApplication")
,[MailAttachment class]
变为 NSClassFromString(@"MailAttachment")
。
我在 Objective-C 中桥接 Keynote 时遇到了类似的问题。只要我不使用下面注释行中的 [ClassName class],我就可以构建而不会出现链接错误:
for (KeynoteIWorkItem* item in selection) {
// if ([item isKindOfClass:[KeynoteShape class]) {
KeynoteShape *shape = (KeynoteShape *)item;
//}
}