Question

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.

Was it helpful?

Solution

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.

OTHER TIPS

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's applicationDidFinishLaunching: 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.:

__attribute__((constructor))
static void initLibrary()
{
    ....
}

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top