gcc: Executing code before main
1
1 8.2 '+load': Executing Code before 'main'
1 =========================================
1
1 This section is specific for the GNU Objective-C runtime. If you are
1 using a different runtime, you can skip it.
1
1 The GNU Objective-C runtime provides a way that allows you to execute
1 code before the execution of the program enters the 'main' function.
1 The code is executed on a per-class and a per-category basis, through a
1 special class method '+load'.
1
1 This facility is very useful if you want to initialize global variables
1 which can be accessed by the program directly, without sending a message
1 to the class first. The usual way to initialize global variables, in
1 the '+initialize' method, might not be useful because '+initialize' is
1 only called when the first message is sent to a class object, which in
1 some cases could be too late.
1
1 Suppose for example you have a 'FileStream' class that declares
1 'Stdin', 'Stdout' and 'Stderr' as global variables, like below:
1
1
1 FileStream *Stdin = nil;
1 FileStream *Stdout = nil;
1 FileStream *Stderr = nil;
1
1 @implementation FileStream
1
1 + (void)initialize
1 {
1 Stdin = [[FileStream new] initWithFd:0];
1 Stdout = [[FileStream new] initWithFd:1];
1 Stderr = [[FileStream new] initWithFd:2];
1 }
1
1 /* Other methods here */
1 @end
1
1
1 In this example, the initialization of 'Stdin', 'Stdout' and 'Stderr'
1 in '+initialize' occurs too late. The programmer can send a message to
1 one of these objects before the variables are actually initialized, thus
1 sending messages to the 'nil' object. The '+initialize' method which
1 actually initializes the global variables is not invoked until the first
1 message is sent to the class object. The solution would require these
1 variables to be initialized just before entering 'main'.
1
1 The correct solution of the above problem is to use the '+load' method
1 instead of '+initialize':
1
1
1 @implementation FileStream
1
1 + (void)load
1 {
1 Stdin = [[FileStream new] initWithFd:0];
1 Stdout = [[FileStream new] initWithFd:1];
1 Stderr = [[FileStream new] initWithFd:2];
1 }
1
1 /* Other methods here */
1 @end
1
1
1 The '+load' is a method that is not overridden by categories. If a
1 class and a category of it both implement '+load', both methods are
1 invoked. This allows some additional initializations to be performed in
1 a category.
1
1 This mechanism is not intended to be a replacement for '+initialize'.
1 You should be aware of its limitations when you decide to use it instead
1 of '+initialize'.
1
Menu