-
Notifications
You must be signed in to change notification settings - Fork 8
Understanding load order of classes and categories
The runtime loads classes, strings and categories.
The addition of a class or category is delayed until all requirements have been met. A category or class may be delayed indefinetely. Strings are added immediately, but they remain unusable until the static string classes (usually NSConstantString and tagged pointer string classes) get loaded.
- It's superclass must be present
- The classes enumerated by
+classDependenciesmust be present - The protocol classes of the class must be present (except if it IS the protocol class)
+classDependenciesis a new feature in mulle-objc 0.4.x
Avoid circular dependencies:
@class Foo; @protocol Foo @end @class Bar; @protocol Bar @end @interface Bar <Foo> @end @interface Foo <Bar> @end
- It's class must be present
- The categories on this class enumerated by
+categoryDependenciesmust be present - The protocol classes of the category must be present
+categoryDependenciesis a new feature in mulle-objc 0.4.x
Assume you have a class Foo, which categories a, b. You want the load order to be Foo, Foo(a), Foo(b).
Specify:
@implementation Foo( b)
+ (SEL *) categoryDependencies
{
static SEL dependencies[] =
{
@selector( a),
0
};
return( dependencies);
}
@end
Foo and Foo( a) are sequenced properly already by the requirements. You just want to make sure that Foo( b) appears after Foo( a).
If you can stick a Foundation library and the application in separate shared libraries, any +load method in the application will find the full set of Foundation functionality available. Problems arise, when you can't or don't want to layer your code with shared libraries.
Then a +load in the application may encounter the Foundation in a partially initialized state. Possibly NSAutoreleasePool for example, may not be present yet!
- Your class exists and can be messaged
- All super classes exist and can be messaged (but they may not have their categories yet!)
- All protocol classes exist and can be messaged (they should not have categories anyway)
- All classes with classids listed in
+classDependenciesexist and can be messaged (but they may not have their categories yet!)
Everything else may not be there or may not be initialized. For example a constant NSString like @"VfL Bochum 1848" may not be usable yet, unless you put @selector( NSConstantString) into the list of classids returned by +classDependencies.
- Your class exists and can be messaged
- All super classes exist and can be messaged (but they may not have their categories yet!)
- All protocol classes exist and can be messaged (they should not have categories anyway)
- All categories of the same class with categories listed in
+categoryDependenciesexist and can be messaged.
It is a bad idea to speculate on any other class existing besides your own class. If you category depends on another class, the class must specify this dependency in +classDependencies. A +classDependencies in the category is ignored.
- If you code a
+loadfunction and you stick with C, you should have no problems. - If you need to use Objective-C, declare the classes you want to use in
+classDependencies. Do not declare abstract classes likeNSStringuse concrete classes like 'NSConstantString". Be sure that the functionality you are expecting is not part of a category! - It's a good idea to check for stuck classes and categories at the start of
main():#if defined( __MULLE_OBJC__) && defined( DEBUG) mulle_objc_check_runtimewaitqueues(); #endif