Am 08.01.2012 um 15:48 schrieb Richard Frith-Macdonald: Hi Richard >> >> --- >> A class’s +load method is called after all of its superclasses' +load >> methods. >> A category +load method is called after the class's own +load method. >> In a +load method, you can therefore safely message other unrelated classes >> from the same image, but any +load methods on those classes may not have run >> yet. > > Your third point here does not follow from the others ... unless by 'safely' > you are talking about a very specific case:
I'd agree if.., but these are not my words. That's a snippet from the NSObject documentation. (http://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSObject_Class/Reference/Reference.html#//apple_ref/occ/clm/NSObject/load) > You can call methods in unrelated classes in the same compilation unit, as > long as those methods do not (directly or indirectly) call other methods > which do not obey the same rule. > So, yes you can construct code which works to call various methods from > +load, but it's so fragile that calling it 'safe' would be perverse. :) > > In practice that boils down to the rule that you can't safely call any ObjC > code from within +load (irrespective of whether you are talking about Apple > or GNU) ... See above documentation snippet, can't agree with you there with respect to Apple. I _can_ safely message some other classes there. I can also not agree with you on GNU, because I can't believe, that self could be nil during a GNU +load. If it can't be nil, then logically there exists a class, with a subset of your projects objc code callable. What this subset is, I will try to deduce form here-on. As David said "+load actually comes with the strongest guarantee, because it guarantees not to be run until after all superclasses have been loaded." IF +load is called, then it comes with this guarantee. BUT +load may also not be called at all... I tested the following two cases. The first is just a class Y, being dependent on X. libX.so: X; +[X load] libY.so: Y:X; +[Y load] main: main.o libX.so libY.so and main: main.o libY.so libX.so Both result in the +load order +[X load] +[Y load] And it works, due to quite an effort on the runtime part, because the +load of subclass may need to be delayed, for the superclass to appear. Here is the example, where it fails. Two independent classes A,B and two categories on A,B. libA.so: A; +[A load] +[B(A) load] libB.so: B; +[B load] +[A(B) load] main: main.o libA.so libB.so or main: main.o libB.so libA.so Depending on the link order, either +[B(A) load] or +[A(B) load] is silently discarded. Ouch! (Or are categories then broken as a whole ? I will assume that just +load is broken, for the rest of this missive.) So aside from +load on categories being broken, what else can be said about the environment of a class or a category in the current GNU runtime with random link order when getting the +load message ? 1) For a class or a category, all superclasses are present, therefore all superclasses +load have executed. This allows your code to message your class and your superclasses, but you need to be sure, that said message is not implemented in a category and that the called message itself isn't calling outside the inheritance chain. (If you subclass NSObject, you strictly speaking can't message NSString or call a method that calls NSString.) 2) Q: If the superclass is NOT in the same image, then can it be said, that all classes in the image, the superclass resides in, have +loaded ? A: No, because some of them may be delayed for their superclass. 3) Q: If it is known, that this other class residing in the image of my superclass has a common superclass with my superclass (f.e. my class subclasses either NSResponder or NSScreen in AppKit, which are both subclasses of NSObject in Foundation). Is it then known that the other class must also have +loaded ? A: Maybe! Imagine two class hierarchies placed into three images X:Y:Z A:Z lib1.so: X lib2.so: Y A lib3.so: Z --- dlopen lib1.so X gets delayed (Y) --- dlopen lib2.so Y and A get delayed (Z) --- dlopen lib3.so Z appears +[Z load] now +[Y load] and either +[X load] +[A load] or +[A load] +[X load] It would be known, that A has loaded before X, if it is guaranteed that delayed subclasses (Y A) of a class (Z) are maintained on a FIFO queue on a placeholder of that class (Z). (Or some similiar mechanism) 4) Q: If 3) is true, is it then known that categories of A,Y,Z, that reside in the dependent images, have +loaded before X ? A: No, not without nontrivial additional effort. > you need to stick to C code in order to avoid someone (perhaps you) coming > back to the code later and inadvertently breaking it by modifying one of > those other methods your +load calls. > > All is not lost though ... you can almost always get the sort of effect you > want by using +load to set variables which are used later in +initialize > methods. Having 3) would be minimal and without 4) I am probably hurting but would be OK. Being realistic, I will stick to non-random link order, where all the rules change! Ciao Nat! ------------------------------------------------------ Thanks for paying my rent. -- EVH _______________________________________________ Gnustep-dev mailing list Gnustep-dev@gnu.org https://lists.gnu.org/mailman/listinfo/gnustep-dev