возможно ли не объявлять ivar, но использовать в synthesize?

#iphone #objective-c

#iPhone #objective-c

Вопрос:

Я смотрю на некоторый пример кода и озадачен отсутствием объявления определенного ivar. Надеюсь, кто-нибудь поможет мне лучше понять это:

 typedef NSUInteger (^NumberOfItemsInSection)(ViewClass *viewClass, NSUInteger section);

// class declaration    
@interface SampleScrollView : UIScrollView
@property (nonatomic, copy) NumberOfItemsInSection itemsSectionBlock;
@end

// class implementation
@implementation SampleScrollView

@synthesize itemsSectionBlock = _itemsSectionBlock;

- (void)setItemsSectionBlock:(NumberOfItemsInSection)itemsSectionBlock
{
    // _itemsSectionBlock is not declared any where in the class 
    // How does the compiler not complain?

    _itemsSectionBlock = [itemsSectionBlock copy];
    [self reloadData];
}

@end
  

Переменная экземпляра «_itemsSectionBlock» нигде не объявлена, и ее можно просто использовать в переопределении параметра установки свойства. Как это работает?

Ответ №1:

Это часть современной среды выполнения и сокращает дублирование кода — объявление IVAR, а затем объявление свойств для этих IVAR.

Это обрабатывается для вас @synthesize

Современная среда выполнения позволяет вам делать другие вещи, которые, как вы думали, вы не могли сделать раньше. Например, теперь вы можете объявлять IVAR в файле .m как часть расширения класса, что уменьшает объем информации, которую вы предоставляете в своем общедоступном интерфейсе.

Обновить

Современный компилятор LLVM 4 даже позволяет отказаться от строки @sytnthesize. Если вы объявите свойство, оно автоматически синтезируется для вас и даже создаст хранилище резервных копий с начальным подчеркиванием.

Комментарии:

1. Позволит ли это определять чисто частные элементы? Можно ли навсегда забыть iVar, используя этот принцип?

2. У вас всегда могут быть чисто частные члены, использующие @private объявление, если вы не ожидаете, что эти IVAR будут совместимы с KVC / KVO. Как только вы объявляете для них сеттеры и геттеры, они становятся доступными с помощью методов, а в Objective-C. нет понятия частных методов. И да, я в основном отказался от объявления IVAR в своих классах.

3. получатели и установщики могут быть объявлены в частном интерфейсе (в .m), чтобы они оставались закрытыми извне. И у вас больше нет проблемы с ограничением KVC / KVO.

4. @Oliver — Не имеет значения, что они объявлены в частном интерфейсе, вы все равно можете вызывать их из-за пределов класса. Методы не могут быть частными в Objective-C.

5. Да, конечно, вы можете их вызывать. Но я имею в виду, что они не видны. Итак, вы должны знать, что вызывать.