discuss-gnustep
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Categories, NSString and +load


From: David Chisnall
Subject: Re: Categories, NSString and +load
Date: Fri, 8 Oct 2010 10:12:35 +0100

I can confirm that this works correctly with libobjc2.  The output is:

2010-10-07 23:22:40.484 test[54937] 1
2010-10-07 23:22:40.487 test[54937] 1

The stuff for handling +load in the runtime (any runtime) is quite horrible.  
It must be called as soon as the class is resolved (not quite when it's loaded 
- all of its superclasses must be loaded first) and it must be called once for 
every definition, even in a category, even in a category that is loaded after 
the class is resolved.

The solution used in libobjc2, which I think is the same as in the GCC runtime, 
is to maintain a hash table of all +load methods that the runtime has called 
and, whenever a category is loaded or class is resolved, to iterate over the 
method lists and see if it can find any that have not been called.  The Apple 
runtime does it in a simpler way, but unfortunately their solution requires 
some support from the loader.  

I hope it's simple to fix for the GCC runtime.  It took me several attempts 
(and bug reports from Quentin) to get this right in libobjc2.

Of course, it's generally a bad idea to rely on +load.  I think I've only ever 
used it twice, and it was only the correct solution in one of those cases.

David

On 8 Oct 2010, at 08:21, Andreas Kostler wrote:

> Hello everyone,
> Please help me on this one. The code snippet below output 
> 1
> 0
> 
> Hence, [NSObject load] gets called, [NSString load] doesn't. 
> Can anyone explain this behaviour?
> Kind Regards
> 
> 
> #include <Foundation/NSString.h>
> #include <Foundation/NSAutoreleasePool.h>
> static int a = 0;
> static int b = 0;
> 
> @implementation NSObject (objectCategory)
> +(void)load {
> a  = 1;
> }
> @end
> 
> @implementation NSString (stringCategory)
> + (void)load {
> b = 1;
> }
> @end
> 
> int main() {
>        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
>        NSLog (@"%d", a);
>        NSLog (@"%d", b);
>        [pool release];
> }
> 
> _______________________________________________
> Discuss-gnustep mailing list
> Discuss-gnustep@gnu.org
> http://lists.gnu.org/mailman/listinfo/discuss-gnustep


-- Sent from my Apple II




reply via email to

[Prev in Thread] Current Thread [Next in Thread]