自定义 Xcode IDE 插件错误:"找不到类名为..."

7
我开发了自己定制的Xcode .ideplugin,以将自定义对象添加到Xcode的对象库面板中。我的自定义对象模板基于一个名为IBMyCustomObject的类,该类的运行时类名是一个名为MyCustomObject的类(运行时类名是在加载Xib文件时将实例化的类的名称)。
经过大量研究,我已成功地使其工作。现在,我可以从“对象库”面板正常地将自定义对象拖放到Xib文件中,在检查器面板中设置对象属性,一切都很好。唯一的问题出现在编译时,当Xib文件被编译时,Xcode的ibtool会给我以下错误:
Exception name: NSInvalidArgumentException
Exception reason: Could not find class named MyCustomObject

这里是完整的异常回溯日志:

Exception backtrace: 
  0. CoreFoundation           0x0226d6d8 __exceptionPreprocess
  1. libobjc.A.dylib          0x01fe98b6 objc_exception_throw
  2. CoreFoundation           0x022fd721 -[NSException raise]
  3. ???                      0x000116b8 [IBCocoaTouchToolObjectPackage initWithRequest:]
  4. ???                      0x00010597 [IBCocoaTouchTool .cxx_destruct]
  5. ???                      0x0000b63d [IBCocoaTouchTool compileNibForRequest:minimumCompatibility:layoutInfo:]
  6. IBFoundation             0x00362c51 __72-[IBMessageReceiveChannel deliverMessage:toTarget:withArguments:result:]_block_invoke
  7. IBFoundation             0x00362996 -[IBMessageReceiveChannel deliverMessage:toTarget:withArguments:result:]
  8. IBFoundation             0x00362673 __80-[IBMessageReceiveChannel runBlockingReceiveLoopNotifyingQueue:notifyingTarget:]_block_invoke
  9. libdispatch.dylib        0x029c2444 _dispatch_barrier_sync_f_slow_invoke
 10. libdispatch.dylib        0x029d34b0 _dispatch_client_callout
 11. libdispatch.dylib        0x029c1766 _dispatch_main_queue_callback_4CF
 12. CoreFoundation           0x022d2b6e __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__
 13. CoreFoundation           0x022137eb __CFRunLoopRun
 14. CoreFoundation           0x02212bf3 CFRunLoopRunSpecific
 15. CoreFoundation           0x02212a0b CFRunLoopRunInMode
 16. Foundation               0x01c1fe55 -[NSRunLoop(NSRunLoop) runMode:beforeDate:]
 17. ???                      0x0003ac67 [IBAbstractCocoaTouchTool startServingReceiveChannel:]
 18. ???                      0x0003ad62 [IBAbstractCocoaTouchTool startServingSocket:]
 19. ???                      0x0003aec7 [IBAbstractCocoaTouchTool protocolCapabilities]
 20. ???                      0x0001053e [IBCocoaTouchTool .cxx_destruct]
 21. libdyld.dylib            0x9313d725 start
Exception info:{
}

有什么方法可以让Xcode(更具体地说是ibtool)知道MyCustomObject类,以便在编译时找到它?我尝试过很多方法,包括将MyCustomObject放入框架并在运行时加载bundle,但没有任何作用。如果我将IBMyCustomObject的runtimeClassName替换为NSMutableDictionary(或任何其他Foundation或UIKit类)而不是MyCustomObject,则一切都能完美地工作,但我确实需要使用自己的MyCustomObject类。

附注:对于所有对开发类似插件感兴趣的人们,我会在sensiblecocoa.com(使用该插件的框架)上发布所有我的发现,并且会详细介绍。


1
你可能需要澄清一下,通过删除Xcode5的主题?!只是说一下。 - Till
1
@ Till NDA 不要发与主题无关的帖子。 - Mick MacCallum
2
好的 - 让我澄清一下我的初始投票(已经被撤销了 - 它收到了2个关闭投票,现在只剩一个)。我从未提到过任何关于保密协议(NDA)的事情。我的观点是不同的;如果一个软件开发人员(或供应商)发布一个预发行版本,通常有一个原因;收集问题报告。如果这些问题报告被发布在开发者的网站之外的任何地方,他很可能得不到反馈。但再次强调,这只是我的个人观点,社区可以做出不同的决定,这就是Stack Overflow的精髓所在。 - Till
@0x7fffffff 更恰当的是这个QA - http://meta.stackexchange.com/questions/137726/limits-of-ios-6-nda/137727#137727 - Sulthan
IB插件自4.x版本起已被弃用。如果编写IBFoundation的人有话要说,我不会感到惊讶这个代码无法编译。 - CodaFi
显示剩余6条评论
1个回答

6

好的,事实证明Xcode(更具体地说是ibtool)在编译时会生成一个全新的进程,称为“Interface Builder Cocoa Touch Tool”,这也解释了为什么加载MyCustomClass包没有任何效果。我考虑的一个可能的解决方案是使用dylib注入将MyCustomClass库注入到新生成的进程中,但我找到的技术都不够可靠,无法用于稳定的生产代码。

最终,我使用了NSMutableDictionary代替MyCustomClass,它编译得非常完美。然后,我使用对象所有者类中的setter属性方法将加载的NSMutableDictionary转换为MyCustomClass,然后手动将所有字典键分配给它们各自的属性。如我之前所说,我将在sensiblecocoa.com博客页面上发布所有插件开发细节。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接