-
Notifications
You must be signed in to change notification settings - Fork 1.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Workaround for JSONKit used in a static library in the device runtime #23
Conversation
ohhorob
commented
May 17, 2011
- NSObject class methods +load and +initialize are not sent to JSONKit classes when they're packaged in a static library
- Testing the static variables before requiring them forces the class to "load" just in time
- NSObject class methods +load and +initialize are not sent to JSONKit classes when they're packaged in a static library - Testing the static variables before requiring them forces the class to "load" just in time
Can you give some more details about when this happens? The proposed fixes should not be required, regardless of whether or not JSONKit is compiled directly in to the app, built as a dynamic library, or a static library. If this is really happening, there's a bug in some part of the compiler/linker toolchain, or the OS linker / objc runtime. What version of the OS(s) do you observe this behavior on? Can you give an example of how you build JSONKit as a static library, and how you link it to your application? |
I have the JSONKit source compiling into my static library target. The header is copied as Public, but the JKDictionary nor JKArray get a +load or +initialize message when the app is run on the device. Other than these load-time messages, everything works perfectly. When run on the simulator, the +load and +initialize are being sent by the runtime (or loader?), and it works without the changes. I tried using +initialize to see if that would get the job done, but that message doesn't come through either. I'll pull together an example project this evening and put it in a public repo on my GitHub account. |
Hi John, I finally got around to whipping up the demo project.. https://github.com/ohhorob/JSONKit-in-framework-demo I've only done a quick and dirty workaround that allows me to keep working on my other project. I'm sure if you considered other strategies you would come up with a better workaround. And if you have a better understanding of the device runtime, it may be that a fix without code changes may be available? Rob. |
I've also put together a question on Stack Overflow, in case it is a problem with the static lib/framework packaging rather than the Objective-C runtime. http://stackoverflow.com/questions/6047903/voidload-message-not-sent-to-framework-class-in-device-runtime |
This may be a "better" solution. Can you give it a try and see if it works? It's harmless if the static variables it sets get set more than once- they will (at least, should) always get set to the exact same values. Place this near extern void jk_hackInit(void) __attribute__ ((constructor)); void jk_hackInit(void) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // Though technically not required, the run time environment at +load time may be less than ideal. _JKArrayClass = objc_getClass("JKArray"); _JKArrayInstanceSize = jk_max(16UL, class_getInstanceSize(_JKArrayClass)); _JKDictionaryClass = objc_getClass("JKDictionary"); _JKDictionaryInstanceSize = jk_max(16UL, class_getInstanceSize(_JKDictionaryClass)); [pool release]; pool = NULL; } |
That works well. I'm curious as to the runtime behaviour that triggers the execution of that method... |
The way I suggested works by using special features of the linker so that it executes a block of code when the executable starts. The block of code executes before You tell the compiler that you want a function called when the executable starts by applying the special The linker is supposed to do the same thing for all The following might be useful: Technical Q&A QA1490 Building Objective-C static libraries with categories. The Tech Q&A suggests that you should pass Maybe you could try and remove all the work arounds and see if |
I just saw in your stackoverflow question that you tried the According to your stackoverflow question, you opened a bug report with Apple regarding this issue: # 9461567, which I'm including in here for completeness sake. |
, the code in the collection classes `+load` was removed and placed in a function with the `__attribute__ ((constructor))` attribute. This is to work around an apparent bug when building JSONKit as a static library for iOS targets. @ohhorob also opened a bug with apple- # 9461567.
…meInitialization(). Missed the JSONDecoder +load stuff on the last commit. Related to issue #23.
Commit cab1ea8 removes the |
Thanks John, JSONKit is now functioning properly when packaged in a static library/framework as of commit cab1ea8ed3449beeb6301a7c47f88c5827e9e47d . |
cross posted on Stack Overflow The |
…ang#23. For issue johnezang#23, the code in the collection classes `+load` was removed and placed in a function with the `__attribute__ ((constructor))` attribute. This is to work around an apparent bug when building JSONKit as a static library for iOS targets. @ohhorob also opened a bug with apple- # 9461567.
…meInitialization(). Missed the JSONDecoder +load stuff on the last commit. Related to issue johnezang#23.