Cocoa Touch / iOS автоматически вызывает любой статический метод класса с именем load - PullRequest
1 голос
/ 20 апреля 2011

Я столкнулся со странным поведением 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.

1 Ответ

5 голосов
/ 20 апреля 2011

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

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

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

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

...