Spec-Zone.ru › GCC 15

9.2 +load: выполнение кода до main

Этот раздел относится только к среде выполнения GNU Objective-C. Если вы используете другую среду выполнения, можете пропустить его.

Среда выполнения GNU Objective-C предоставляет способ выполнить код до того, как выполнение программы перейдёт к функции 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

© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-15.3.0/gcc/Executing-code-before-main.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API