Рекомендации по использованию переменных @property

Может ли кто-нибудь поделиться некоторыми знаниями о том, что является передовой практикой/соглашением о коде при использовании @property iVars в методах инициализации или назначенных инициализаторах?

пожалуйста, посмотрите мой пример:

@interface MyClass ()
@property(nonatomic,strong) nsstring *tempString;
@property(nonatomic,strong) NSMutableArray *arrItems;
@end

@implementation ViewController

- (id)init
{
    if (self = [super init]) {

        //Is this best practice / correct
        _tempString = @"";
        _arrItems = [[NSMutableArray alloc] initWithCapacity:0];
        ...
        ...

        //Or this
        self.tempString = @"";
        self.arrItems = [[NSMutableArray alloc] initWithCapacity:0];
    }
    return self;
}

@end

Любые советы о том, почему следует использовать тот или иной?

Спасибо...


person Garry.S    schedule 05.10.2012    source источник
comment
В вашем примере я бы обычно присваивал значение с помощью установщика свойств, например. self.tempString = @"Some Value";. Причина в том, что у вас может быть некоторая пользовательская логика в сеттере. Например, возможно, ваш установщик tempString хотел бы удалить тире из номера телефона. Если вы присвоите значение непосредственно ivar, вы обойдете эту логику. Идея состоит в том, чтобы использовать сеттер, если он у вас есть, если только вы не видите причины НЕ делать этого. Просто примечание: если вы назначаете непосредственно ivars, вам нужно будет самостоятельно управлять структурой сохранения/копирования/атома (сеттеры обрабатывают это, если не переопределить).   -  person Jeremy    schedule 05.10.2012


Ответы (5)


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

person Rob    schedule 05.10.2012

Прочтите эту тему: Почему не следует Я использую методы доступа Objective C 2.0 в init/dealloc?

Другими словами, если вы не собираетесь использовать KVO, вы можете использовать второй подход:

//Or this
        self.tempString = @"";
        self.arrItems = [[NSMutableArray alloc] initWithCapacity:0];

Но будьте осторожны с alloc-init, не забывайте об autorelease.

person Igor Pchelko    schedule 05.10.2012
comment
Судя по наличию strong в его примере кода, он должен использовать ARC, поэтому autorelease не применимо. - person Rob; 05.10.2012
comment
Спасибо за ответ, но если я назначу напрямую _tempString, мне не нужно будет сохранять/копировать в ARC, я правильно понял? - person Garry.S; 06.10.2012

Обычно лучше использовать обозначение свойства, когда вы его определяете, частично (в основном?) по причине, упомянутой Джереми.

Отладка конкретной переменной становится намного проще, когда вы можете установить точку останова в переопределении установщика метода и применить ее ко ВСЕМ путям кода, которые изменяют переменную.

Другая причина заключается в том, чтобы поддерживать согласованную модель управления памятью, хотя это менее важно, поскольку вы используете ARC. Однако, если бы это было не так, и было бы сохранено значение strong, то вы должны были бы убедиться, что объект, который вы устанавливаете для свойства, автоматически освобождается везде, где вы устанавливаете свойство, и вам не нужно иметь дело с освобождением текущего значения, если вы напрямую устанавливаете свойство. Переменная.

Согласованность важна для обслуживания/удобочитаемости и отладки, независимо от того, какие методы вы используете.

person Matt    schedule 05.10.2012

Я предпочитаю ленивый метод создания экземпляров свойств.

После того, как вы @synthesize, вы можете переопределить свой геттер, чтобы лениво создавать экземпляр вашего свойства.

Например:

-(NSString *)tempString {

    if(!tempString) {
        _tempString = @"";
    }
    return _tempString;
}

а также

-(NSMutableArray *)arrItems {

    if(!_arrItems) {
        _arrItems = [[NSMutableArray alloc] initWithCapacity:0];
    }
    return _arrItems;
}

Если вы хотите установить свое свойство в методе init, используйте точечную нотацию self.myProperty, чтобы он использовал определенный установщик для свойства, а не метод частного класса напрямую.

person James McCracken    schedule 05.10.2012

Согласно Apple, вы не должны не использовать методы доступа в init... или dealloc методах:

Вы всегда должны обращаться к переменным экземпляра непосредственно из метода инициализации, потому что во время установки свойства остальная часть объекта может быть еще не полностью инициализирована. Даже если вы не предоставляете собственные методы доступа или не знаете о каких-либо побочных эффектах внутри вашего собственного класса, будущий подкласс вполне может переопределить поведение.

Взято из этого документа: Инкапсуляция данных .

person Monolo    schedule 05.10.2012