Какао Touch / iOS автоматически вызывает любой статический метод класса с именем load

Я столкнулся со странным поведением Cocoa Touch / iOS с использованием статического метода. Если вы реализуете статический метод load в любом классе, Cocoa Touch / iOS автоматически вызовет этот метод при запуске приложения. Даже если вы не ссылаетесь на этот класс из основного потока выполнения, он все равно будет вызываться первым, несмотря ни на что.

Мне удалось воспроизвести поведение при компиляции на SDK 4.2 на Xcode 3.2.5 и SDK 4.3 на Xcode 4.0.1, а также при запуске как с симулятора iPhone, так и с устройства iPhone.

Вот как воспроизвести:

Создайте новый класс и назовите его как хотите. В интерфейсе объявите статический метод load (любой возвращаемый тип):

+ (void)load;

Затем реализуйте это:

+ (void)load {
    NSLog(@"What the?");
}

Скомпилируйте (убедитесь, что новый класс скомпилирован) и запустите приложение (на симуляторе или устройстве). Пока приложение запускается, переключитесь в режим просмотра GDB и следите за ним. Вы увидите "Что за?" повторяется там, хотя по логике никакой другой код не ссылается на класс или метод.

И вдобавок ко всему, если вы используете какой-либо код автозапуска в методе, вы получите сообщение об ошибке, которое показывает, что метод вызывается даже раньше, чем метод int main() (супер-шлюз всех существующих приложений C).

Следующий код:

+ (void)load {
    NSLog(@"Hello %@", [NSString stringWithString:@"World"]);
}

Дам вам что-то вроде:

2011-04-21 00:41:53.828 AppName[548:707] *** __NSAutoreleaseNoPool(): Object 0x8fe8c of class NSCFString autoreleased with no pool in place - just leaking
2011-04-21 00:41:53.838 AppName[548:707] Hello World

Итак, вопрос в том, знает ли кто-нибудь, почему Cocoa Touch / iOS вызывает этот метод? Что такого особенного в имени метода load? И последнее, но не менее важное: это функция или ошибка?

p / s: Я обнаружил это поведение, когда так случилось, что реализованный мной статический метод load создает экземпляры многих автоматически выпущенных объектов, и я был озадачен множеством __NSAutoreleaseNoPool() предупреждающих сообщений в GDB.


person Lukman    schedule 20.04.2011    source источник


Ответы (1)


NSObject имеет метод загрузки + (void). Вот что говорится в документации:

Вызывается всякий раз, когда класс или категория добавляются в среду выполнения Objective-C; реализовать этот метод для выполнения специфичного для класса поведения при загрузке.

Так что это работает, как задумано, и не является ошибкой. Этот метод вызывается каждым классом, когда он добавляется в среду выполнения, то есть до того, как любой код начинает выполняться.

Источник: документация по NSObject

person Christian    schedule 20.04.2011