не правильный.

овном у меня есть следующий код (объяснено здесь:Константы Objective-C в протоколе)

// MyProtocol.m
const NSString *MYPROTOCOL_SIZE;
const NSString *MYPROTOCOL_BOUNDS;

@implementation NSObject(initializeConstantVariables)

+(void) initialize {
     if (self == [NSObject class])
     {
         NSString **str = (NSString **)&MYPROTOCOL_SIZE;
         *str = [[MyClass someStringLoadedFromAFile] stringByAppendingString:@"size"];
         str = (NSString **)&MYPROTOCOL_BOUNDS;
         *str = [[MyClass someStringLoadedFromAFile] stringByAppendingString:@"bounds"];
     }
}

@end

Мне было интересно: безопасно ли мне иметь категорию, которая переопределяет объект NSObject?+initialize метод?

 Frank C.12 янв. 2011 г., 13:47
Во-первых, вам не нужно создавать категорию, чтобы во время выполнения вызывать вашу 'initialize', она будет делать это автоматически перед отправкой любого сообщения. Во-вторых, что вы подразумеваете под «безопасным»? Кто-нибудь читает документацию больше ???
 Richard J. Ross III12 янв. 2011 г., 13:51
Посмотрите на категорию ... Это перезапись класса NSObject, а не моего класса. Я пытаюсь получить метод, который, как я знаю, будет вызываться в начале любой программы, использующей созданную мной среду.

Ответы на вопрос(3)

также, почему вы не используете аксессоры? Вместо того, чтобы иметь поддельную постоянную переменную, которая приходит из ниоткуда, предпочтительно определить метод доступа к классу, который должен фактически использовать его. Простой + (NSString *) myProtocolSize; было бы здорово, даже в протоколе.

Кроме того, переопределение методов класса в категории «работает», но не является надежным, и его следует избегать любой ценой: если переопределяемый метод реализован в категории, среда выполнения НЕ гарантирует порядок загрузки и вашу реализацию. никогда не может быть добавлен к нему.

 Richard J. Ross III12 янв. 2011 г., 14:46
На самом деле существует более 20 констант, и создание класса действительно непростительно.
Решение Вопроса

+initialize методы в категориях на занятиях. В итоге вы замените существующую реализацию, если она есть, и если две категории одного класса будут реализованы+initialize, нет гарантии, которая будет выполнена.

+load имеет более предсказуемое и четко определенное поведение, но случается слишком рано, чтобы делать что-либо полезное, потому что многие вещи находятся в неинициализированном состоянии.

Лично я пропускаю+load или же+initialize в целом и использовать аннотацию компилятора, чтобы заставить функцию выполняться при загрузке базового двоичного файла / dylib. Тем не менее, в это время вы мало что можете сделать безопасно.

__attribute__((constructor))
static void MySuperEarlyInitialization() {...}

Вам гораздо лучше выполнить инициализацию в ответ на запуск приложения.NSApplication а такжеUIApplication оба предлагают зацепки делегата / уведомления для введения небольшого количества кода в приложение, когда оно запускается.

 bbum12 янв. 2011 г., 19:29
Да, это будет работать нормально. Статическая библиотека - это не что иное, как коллекция файлов .o, которые связаны с приложением, как если бы они были скомпилированы в первую очередь. Тем не менее, обратите внимание, что отсутствие инициализации в таких конструкторах - лучший долгосрочный план ....
 Richard J. Ross III12 янв. 2011 г., 19:02
Спасибо! Я вроде думал, что должно быть что-то подобное .... мой единственный вопрос, будет ли это работать для статической библиотеки?

Переменная типаNSString *const всегда будет инициализироваться до запуска вашего кода, при условии, что мы пока игнорируем капризы C ++:

NSString *const MY_PROTOCOL_SIZE = @"...";

Переменная типаconst NSString * (const Ключевое слово, применяемое к кишкамNSString(не его адрес) может быть изменен любым кодом, но не может иметь отправленные ему сообщения. Это побеждает цель сделать этоconst, Рассмотрим вместо этого глобальную функцию:

static NSString *GetMyProtocolSize(void) {
    return [[MyClass someStringLoadedFromAFile] ...];
}

Или используйте метод класса:

@implementation MyClass
+ (NSString *)myProtocolSize {
    return [[MyClass someStringLoadedFromAFile] ...];
}
@end

Вы задали вопрос ранее о том, почему вашconst Строки не будут принимать динамические значения - это потому, что вы, кажется, не понимаете, чтоconst делает с символом. Вы должны прочитать о значенииconst Ключевое слово в C и должен смотреть на другой подход к получению ваших строк, еслиconst не правильный.

Ваш ответ на вопрос