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