Объекты alloc-init в методе +(void)initialize для многократного их использования

Я использую NSDateFormatter объект (настроенный для определенных целей) несколько раз. Поскольку я не эксперт по предметам, я нашел три различных подхода к решению этой проблемы.

В первом я создал NSDateFormatter категория и настроить код там. Это обычный подход, но каждый раз, когда я создаю такой объект, он помещается в основной пул автоматического выпуска. Такое поведение, я думаю, справедливо как для не-ARC, так и для кода ARC.

Во втором вместо этого я переопределил +(void)initialize метод и поместите код настройки там. Вот простой пример:

static NSDateFormatter* dateFormatter = nil;

+(void)initialize
{
    dateFormatter = [[NSDateFormatter alloc] init];
    // other code here
}

Наконец, я настроил третий подход, используя ленивую загрузку экземпляров через свойства, подобные следующим:

-(NSDateFormatter)dateFormatter
{
    if(dateFormatter) return dateFormatter;        
    // alloc-init here
}

Сказав это, я хотел бы знать, какой подход является наиболее подходящим для работы с объектами несколько раз, и если, используя +(void)initialize таким образом, это правильно.

Заранее спасибо.

2 ответа

Решение

Оба последующих метода верны, но я верю, что вы хотите соединить их!

static NSDateFormatter *sharedInstance = nil;

+ (NSDateFormatter *)sharedInstance {
    if (sharedInstance == nil) {
        sharedInstance = [[NSDateFormatter alloc] init];
    }
    return sharedInstance;
}

Примечание: такие классы называются синглетонами. Прочитайте больше

По сути, мой любимый образец - тот, который уже дал mindw0rk (я уже проголосовал за его ответ). Он имеет преимущество в том, что вы можете поместить метод в категорию NSDateFormatter, Я бы немного изменил это так:

+ (NSDateFormatter *)sharedInstance {
    static NSDateFormatter *sharedInstance = nil;
    if (sharedInstance == nil) {
        sharedInstance = [[NSDateFormatter alloc] init];
    }
    return sharedInstance;
}

так что вы не можете случайно упомянуть sharedInstance без предварительной инициализации.

Если у вас есть более одного общего экземпляра, вы можете использовать разные методы для получения каждого, например

+ (NSDateFormatter *)dateFormatterForFoo {
    static NSDateFormatter *sharedInstance = nil;
    if (sharedInstance == nil) {
        sharedInstance = [[NSDateFormatter alloc] init];
    }
    return sharedInstance;
}

+ (NSDateFormatter *)dateFormatterForBar {
    static NSDateFormatter *sharedInstance = nil;
    if (sharedInstance == nil) {
        sharedInstance = [[NSDateFormatter alloc] init];
    }
    return sharedInstance;
}

Или, если каждый настроенный форматер даты имеет свой собственный подкласс, каждый из них может реализовать +sharedInstance вернуть объект правильного класса.

Или вы можете иметь словарь форматирования даты:

+ (NSDateFormatter *)customisedFormatterForKey: (NSString*) key {
    static NSDictionary *sharedInstances = nil;
    if (sharedInstance == nil) {
        sharedInstance = [[NSDictionary alloc] initWithObjectsAndKeys: ....];
    }
    return [sharedInstance objectForKey: key];
}

У меня есть несколько комментариев на -initialize подход.

Вы должны быть немного осторожны с использованием -initialize, Он вызывается один раз перед первым использованием класса. Если вы никогда не используете класс, он никогда не будет вызван. Итак, чтобы ваш код работал, вы должны убедиться, что отправляете сообщение NSDateFormatter или экземпляр NSDateFormatter прежде чем начать использовать общий экземпляр dateFormatter, Обратите внимание, что отправка сообщения самому dateFormatter не считается. Это потому что начинается nil и, следовательно, не имеет класса.

Другие вопросы по тегам