+(void)加载消息未发送到设备运行时中的框架类
我已经在这里搜索了关于 SO 的问题,寻找任何关于为什么我看到这种行为的提示,但什么也没有。
考虑一个类(实际上是两个表现出相同问题的类),内置于静态库中,包装在框架包中(使用的步骤)。它们继承自 Foundation 框架类集群 (NSMutableDictionary
和 NSMutableArray
)。
这些类的使用依赖于在使用静态函数(不是类方法!)来分配和初始化实例(我猜是一种工厂辅助函数?)之前初始化一些静态变量。
当 iOS 应用程序项目链接到该框架时,模拟器和设备之间的 Objective-C 运行时类加载行为存在差异。
具体来说,在设备(iPhone 4、iOS 4.3.3)上,当加载应用程序时,这些类不会收到 +load
消息,并且静态变量不会初始化,因此静态工厂方法失败。在模拟器上,消息被发送,并且一切都按预期进行。设备运行时是否有问题?
我的问题是,我的框架是否可以进行不同的配置以确保发送 +load
消息?或者我在 iOS 中遇到了静态库/框架类加载的错误吗?
这些类来自 JSONKit 库 (JKArray
, JKDictionary
)。
说明此问题的示例项目位于此处 - https://github.com/ohhorob/JSONKit -in-framework-demo
编辑:根据@bbum的建议,我已经验证了 JKDictionary
和 JKArray
类实际上已加载并可用,而应用程序是 跑步。 GitHub 项目上的 DeviceBroken
分支已使用所使用的验证进行更新。
我向 Apple 提交了错误报告 (#9461567)。
I've trawled through questions here on SO looking for any hints to why I'm seeing this behaviour, and nothing yet.
Consider a class (actually two classes exhibiting the same problem), built into a static library, wrapped in a framework bundle (steps used). They inherit from Foundation framework class clusters (NSMutableDictionary
and NSMutableArray
).
The use of these classes relies on some static variables being initialised before a static function (not class method!) is used to allocate and initialise an instance (a kind of factory helper function I guess?).
When an iOS app project links to that framework there is a difference the Objective-C runtime class loading behaviour between the Simulator and the Device.
Specifically, on a device (iPhone 4, iOS 4.3.3) when the app is loaded these classes do not get a +load
message, and the static vars do not initialize, therefore the static factory method fails. On the Simulator, the messages are sent, and all works as intended. Could it be a problem with the Device runtime having a
My question is, can my framework be configured differently to ensure the +load
messages are sent? Or have I run into a bug with static library/framework class loading in iOS?
The classes are from the JSONKit library (JKArray
, JKDictionary
).
An example project that illustrates this problem is here – https://github.com/ohhorob/JSONKit-in-framework-demo
EDIT: As per @bbum's suggestion, I've verified that the JKDictionary
and JKArray
classes are in fact loaded and available while the application is running. The DeviceBroken
branch on the GitHub project is updated with the verification used.
I filed a bugreport (#9461567) with Apple.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
不会调用
+load
方法,因为您实际上没有创建静态库,而是创建可重定位对象文件包 。如果您使用 make-fmwk 或 iOS 通用框架 模板,然后加载方法将按预期调用。The
+load
methods are not called because you did not actually create a static library but a Relocatable Object File bundle. If you create the static framework with either make-fmwk or the iOS Universal Framework template then the load methods will be called as expected.奇怪的;我会做一个
NSLog(@"klassy klass %@", [MysteryClass class]);
并确保类实际上已加载(但请参见下文 - 这可能会“解决”问题) 。如果是,那么这是 DYLD 加载程序中的错误,请归档。
如果不是,那么链接器很可能正在剥离类,因为没有任何东西直接引用它们。尝试在应用程序的
applicationDidFinishLaunching:
方法中添加[MysteryClass class]
(无论在哪里,甚至是否执行它都无关紧要......但这将是一个明显点)。另外,我建议不要使用 +load ,而是编写构造函数。即:
如果这是链接器问题,则可能会也可能不会解决问题。然而,它比相当神奇的
+load
方法更清楚地表达您的意图。Odd; I'd do an
NSLog(@"klassy klass %@", [MysteryClass class]);
and make sure the classes are actually loaded (but see below -- this may "fix" the problem).If they are, then this is a bug in the DYLD loader and please file it.
If not, then it is likely that the linker is stripping the class(es) because nothing references them directly. Try adding
[MysteryClass class]
in the app'sapplicationDidFinishLaunching:
method (doesn't really matter where or, even, if it gets executed... but that'll be an obvious spot).Also, I'd suggest not using
+load
and, instead, writing a constructor function. I.e.:If this is a linker issue, that may or may not fix the problem. It is, however, much clearer as to your intentions than the rather magical
+load
method.