8.2 +load: Выполнение кода перед main
Этот раздел предназначен для GNU Objective-C runtime. Если вы используете другой runtime, можете его пропустить.
GNU Objective-C runtime предоставляет возможность выполнения кода перед тем, как выполнение программы войдёт в функцию main. Код выполняется для каждого класса и каждой категории через специальный метод класса +load.
Эта возможность очень полезна, если необходимо инициализировать глобальные переменные, к которым программа может получить доступ напрямую, не отправляя сообщение классу сначала. Обычный способ инициализации глобальных переменных в методе +initialize может быть неэффективным, так как +initialize вызывается только при первом отправлении сообщения объекту класса, что в некоторых случаях может произойти слишком поздно.
Предположим, например, у вас есть класс FileStream, который объявляет Stdin, Stdout и Stderr как глобальные переменные, как показано ниже:
FileStream *Stdin = nil;
FileStream *Stdout = nil;
FileStream *Stderr = nil;
@implementation FileStream
+ (void)initialize
{
Stdin = [[FileStream new] initWithFd:0];
Stdout = [[FileStream new] initWithFd:1];
Stderr = [[FileStream new] initWithFd:2];
}
/* Other methods here */
@end
В этом примере инициализация Stdin, Stdout и Stderr в +initialize происходит слишком поздно. Разработчик может отправить сообщение одному из этих объектов до фактической инициализации переменных, тем самым отправив сообщения объекту nil. Метод +initialize, который фактически инициализирует глобальные переменные, не вызывается до первого отправления сообщения объекту класса. Решение потребовало бы инициализации этих переменных непосредственно перед входом в main.
Правильное решение вышеуказанной проблемы заключается в использовании метода +load вместо +initialize:
@implementation FileStream
+ (void)load
{
Stdin = [[FileStream new] initWithFd:0];
Stdout = [[FileStream new] initWithFd:1];
Stderr = [[FileStream new] initWithFd:2];
}
/* Other methods here */
@end
+load — это метод, который не переопределяется категориями. Если класс и его категория оба реализуют +load, оба метода вызываются. Это позволяет выполнять дополнительные инициализации в категории.
Этот механизм не предназначен для замены +initialize. Необходимо учитывать его ограничения при принятии решения об использовании вместо +initialize.
| • Что можно и что нельзя делать в +load: |
Далее: Кодирование типов, Предыдущее: API GNU Objective-C runtime, Вверх: Objective-C [Оглавление][Индекс]
© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-8.5.0/gcc/Executing-code-before-main.html