четверг, 9 июня 2011 г.

IBOutlet. Инструкция по применению. Эпизод 2

С год назад я написал заметку «IBOutlet. Инструкция по применению», где рассмотрел вариации работы с IBOutlet'ами. Однако спустя чуть больше, чем полгода, эта статья кажется мне неполной. А потому вторым эпизодом хочу внести в нее необходимые дополнения.

Итак, поехали. Если помните, итоговый вариант, к которому я привел вас в той статье был:

    @interface MyClass: NSObject
    {
        UIView *_smth;
    }
    @property (nonatomic, retain) IBOutlet UIView* smth;
    ...

    @implementation
    @synthesize smth = _smth;
    ...

Так вот, в случае современной разработки этот вариант не является лучшим. Что я имею ввиду?!

Обратимся сначала к документу «The Objective-C Programming Language», раздел «Declared Properties», секция «Property Implementation Directives». Суть написанного там — что есть два так называемых времени выполнения (переведите «runtime» сами как хотите, по логике «окружение» подходит лучше) — устаревший («legacy») и современный («modern»). Причем в современном директива @synthesize самостоятельно создает переменную, если таковой нет.

Теперь надо разобраться, в каком окружении вы работаете. Тут все просто — смотрим документ «Objective-C Runtime Programming Guide». Там, в разделе «Platforms» пишут, что современное окружение (ну, не могу я больше называть это временем выполнения) — это iPhone (точнее iOS, просто документ не обновлялся с 2009 года) и 64-битные приложения на Mac OS X v10.5 и выше; все остальное — устаревшее.

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

    @interface MyClass: NSObject
    {
    }
    @property (nonatomic, retain) IBOutlet UIView* smth;
    ...

    @implementation
    @synthesize smth = _smth;
    ...

В результате получим:
 а) свойство smth, с которым можно удобно работать извне;
 б) приватное поле данных (переменную) _smth, которое можно спокойно использовать, словно обычным образом объявленное.

В довесок хочу напомнить, что все IBOutlet'ы связываются с соответствующими элементами nib-файла во время загрузки. Соответственно, после выгрузки приложения можно их «отцепить» вручную — чтобы не занимали память, все равно потом будут заново инициализированы:

    - (void)viewDidUnload
    {
        self.smth = nil;
        [super viewDidUnload];
    }

Однако, если вы этого не сделаете — ничего слишком страшного не случится. Просто в случае выгрузки контроллера без уничтожения (привет, сообщения о нехватке памяти!) у вас будет занята лишняя память, а потом при новой загрузке с nib-файла зачения свойств все равно будут заменены на заново инициализированные (старое будет уничтожено).

Вот как-то так!

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

Отправить комментарий