]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/doc/gcc/gnu-objective-c-features/load-executing-code-before-main.rst
sphinx: add missing trailing newline
[thirdparty/gcc.git] / gcc / doc / gcc / gnu-objective-c-features / load-executing-code-before-main.rst
CommitLineData
c63539ff
ML
1..
2 Copyright 1988-2022 Free Software Foundation, Inc.
3 This is part of the GCC manual.
4 For copying conditions, see the copyright.rst file.
5
6.. _executing-code-before-main:
7
8+load: Executing Code before main
9*********************************
10
11This section is specific for the GNU Objective-C runtime. If you are
12using a different runtime, you can skip it.
13
14The GNU Objective-C runtime provides a way that allows you to execute
15code before the execution of the program enters the ``main``
16function. The code is executed on a per-class and a per-category basis,
17through a special class method ``+load``.
18
19This facility is very useful if you want to initialize global variables
20which can be accessed by the program directly, without sending a message
21to the class first. The usual way to initialize global variables, in the
22``+initialize`` method, might not be useful because
23``+initialize`` is only called when the first message is sent to a
24class object, which in some cases could be too late.
25
26Suppose for example you have a ``FileStream`` class that declares
27``Stdin``, ``Stdout`` and ``Stderr`` as global variables, like
28below:
29
30.. code-block:: objective-c
31
32 FileStream *Stdin = nil;
33 FileStream *Stdout = nil;
34 FileStream *Stderr = nil;
35
36 @implementation FileStream
37
38 + (void)initialize
39 {
40 Stdin = [[FileStream new] initWithFd:0];
41 Stdout = [[FileStream new] initWithFd:1];
42 Stderr = [[FileStream new] initWithFd:2];
43 }
44
45 /* Other methods here */
46 @end
47
48In this example, the initialization of ``Stdin``, ``Stdout`` and
49``Stderr`` in ``+initialize`` occurs too late. The programmer can
50send a message to one of these objects before the variables are actually
51initialized, thus sending messages to the ``nil`` object. The
52``+initialize`` method which actually initializes the global
53variables is not invoked until the first message is sent to the class
54object. The solution would require these variables to be initialized
55just before entering ``main``.
56
57The correct solution of the above problem is to use the ``+load``
58method instead of ``+initialize`` :
59
60.. code-block:: objective-c
61
62 @implementation FileStream
63
64 + (void)load
65 {
66 Stdin = [[FileStream new] initWithFd:0];
67 Stdout = [[FileStream new] initWithFd:1];
68 Stderr = [[FileStream new] initWithFd:2];
69 }
70
71 /* Other methods here */
72 @end
73
74The ``+load`` is a method that is not overridden by categories. If a
75class and a category of it both implement ``+load``, both methods are
76invoked. This allows some additional initializations to be performed in
77a category.
78
79This mechanism is not intended to be a replacement for ``+initialize``.
80You should be aware of its limitations when you decide to use it
81instead of ``+initialize``.
82
83.. toctree::
84 :maxdepth: 2
85
86
87.. _what-you-can-and-what-you-cannot-do-in-+load:
88
89What You Can and Cannot Do in +load
90^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
91
92``+load`` is to be used only as a last resort. Because it is
93executed very early, most of the Objective-C runtime machinery will
94not be ready when ``+load`` is executed; hence ``+load`` works
95best for executing C code that is independent on the Objective-C
96runtime.
97
98The ``+load`` implementation in the GNU runtime guarantees you the
99following things:
100
101* you can write whatever C code you like;
102
103* you can allocate and send messages to objects whose class is implemented
104 in the same file;
105
106* the ``+load`` implementation of all super classes of a class are
107 executed before the ``+load`` of that class is executed;
108
109* the ``+load`` implementation of a class is executed before the
110 ``+load`` implementation of any category.
111
112In particular, the following things, even if they can work in a
113particular case, are not guaranteed:
114
115* allocation of or sending messages to arbitrary objects;
116
117* allocation of or sending messages to objects whose classes have a
118 category implemented in the same file;
119
120* sending messages to Objective-C constant strings (``@"this is a
121 constant string"``);
122
123You should make no assumptions about receiving ``+load`` in sibling
124classes when you write ``+load`` of a class. The order in which
125sibling classes receive ``+load`` is not guaranteed.
126
127The order in which ``+load`` and ``+initialize`` are called could
128be problematic if this matters. If you don't allocate objects inside
129``+load``, it is guaranteed that ``+load`` is called before
130``+initialize``. If you create an object inside ``+load`` the
131``+initialize`` method of object's class is invoked even if
132``+load`` was not invoked. Note if you explicitly call ``+load``
133on a class, ``+initialize`` will be called first. To avoid possible
134problems try to implement only one of these methods.
135
136The ``+load`` method is also invoked when a bundle is dynamically
137loaded into your running program. This happens automatically without any
138intervening operation from you. When you write bundles and you need to
139write ``+load`` you can safely create and send messages to objects whose
140classes already exist in the running program. The same restrictions as
3ed1b4ce 141above apply to classes defined in bundle.