Не должен IBOutlet, чтобы быть собственность и синтезированных?
в большинстве примеров я вижу следующую настройку IBOutlets:
(Example A)
FooController.h:
@interface FooController : UIViewController {
UILabel *fooLabel;
}
@property (nonatomic, retain) IBOutlet UILabel *fooLabel;
@end
FooController.m:
@implementation FooController
@synthesize fooLabel;
@end
но это работает также отлично (обратите внимание: нет свойства и нет синтезировать):
(Example B)
FooController.h:
@interface FooController : UIViewController {
IBOutlet UILabel *fooLabel;
}
@end
FooController.m:
@implementation FooController
@end
есть ли какие-либо недостатки определения IBOutlets, как в примере B? Как утечка памяти? Кажется, работает нормально, и я предпочитаю не выставлять IBOutlets как общедоступные свойства, поскольку они не используются как таковые, они используются только в реализации контроллера. Определение его в трех местах без реальной необходимости не поражает мне же очень сухо (не повторяйтесь).
4 ответа:
в Mac OS X IBOutlets подключаются следующим образом:
- найдите метод set
:. Если он существует, назовите его. - Если метод не существует, найдите переменную экземпляра с именем
, установите ее без удержания. на iPhone OS IBOutlets подключаются следующим образом:
- вызов [объект setValue: outletValue forKey:@ "
"] поведение заданного значения для ключа сделать что-то вроде этого:
- найдите метод set
:. Если он существует, назовите его. - Если метод не существует, найдите переменную экземпляра с именем
, установите ее и сохранить его. Если вы используете свойство, вы попадете в "найдите метод set
:... " случай на обеих платформах. Если вы просто используете переменную экземпляра, то у вас будет другое поведение сохранения/выпуска на Mac OS X VS iPhone OS. Нет ничего плохого в использовании переменной экземпляра, вам просто нужно иметь дело с этой разницей в поведении при переключении между платформами.вот ссылка на полную документацию на эту тему. https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/LoadingResources/CocoaNibs/CocoaNibs.html#//apple_ref/doc/uid/10000051i-CH4-SW6
в Mac OS X IBOutlets не сохраняются по умолчанию. Это противоположно поведению на iPhone OS: на iPhone OS, если вы не объявляете свойство, оно сохраняется, и вы должны освободить это свойство в
dealloc
метод. Кроме того, 64-разрядная среда выполнения может синтезировать переменные экземпляра с помощью объявлений свойств. Это означает, что когда-нибудь переменные экземпляра (сIBOutlet
) могут быть опущены.по этим причинам он более однороден и совместимы для создания всегда свойство и использовать
IBOutlet
только в собственность. К сожалению, он также более многословен.в вашем первом примере, вы всегда должны освободить розетку в
dealloc
метод. Во втором примере вы должны выпустить розетку только с iPhone OS.
конечный результат точно такой же, но вы должны держать несколько вещей в виду:
при использовании полей экземпляра в качестве выходов, вы не должны выпускать их в dealloc.
при использовании свойств, которые имеют атрибут (сохранить), вы должны освободить имущество в dealloc (через
self.property=nil
или отпуская переменную поддержки). Это делает его намного более прозрачным относительно того, что происходит на.на самом деле все сводится к одному и тому же старому правилу: "ты должен освободить то, что ты выделяешь / сохраняешь". Поэтому, если вы используете поле экземпляра в качестве выхода, вы не выделили/сохранили его, поэтому вы не должны его освобождать.
возможно, что эти примеры используют сохранение, потому что пример кода программно выделяет и инициализирует UILabel, а затем добавляет его в UIView. Это относится ко многим примерам, так как обучение использованию Interface Builder часто не является их целью.
второй пример (без свойства и без синтеза) с IBOutlet используется, когда разработчик "назначает" UILabel (Button, View и т. д.) В Построителе интерфейса-путем перетаскивания IBOulet в Метка или другой компонент представления. На мой взгляд, предыдущее действие перетаскивания (метка на вид) также добавляет подвид, метку к виду-и так далее. Метка сохраняется видом; вид сохраняется окном; окно сохраняется владельцем файла. Владельцем файла обычно является ваш документ, который загружается в main.
вы заметите, что при переходе через вашу программу (путем добавления awakeFromNib
- (void)awakeFromNib { [fooLabel blahblah]; }
у этого дурака уже есть память адрес.
это потому, что метка была инициализирована из пакета файлов (файл nib) с использованием не init, а initWithCoder. Который по существу десериализует filestream в объект-а затем устанавливает переменную IBOutlet. (Мы все еще говорим о методе IBOutlet).
также обратите внимание, что вышеупомянутый метод iOS использует метод значения ключа
call [object setValue:outletValue forKey:@"<OutletName>"]
, который является наблюдателя/наблюдаемого паттерна. Этот шаблон требует Ссылки на наблюдаемый объект каждый Наблюдатель в наборе / массиве. Изменение значения будет повторять набор/массив и одинаково обновлять всех наблюдателей. Этот набор уже сохранит каждого наблюдателя, таким образом, отсутствие сохранения в iOS.
дальше и дальше идет спекуляция.
похоже, что случаи, когда вы используете Interface Builder, то
@property (nonatomic, retain) IBOutlet UILabel *fooLabel;
возможно, следует изменить на
@property (nonatomic, weak) IBOutlet UILabel *fooLabel;
или @property (nonatomic, assign) IBOutlet UILabel * fooLabel;
и тогда это не должно быть выпущен в методе dealloc. Кроме того, он будет удовлетворять требованиям OSX и iOS.
это основано на логике, и я мог бы пропустить некоторые части здесь.
тем не менее, это может не иметь значения, если представление является постоянным в течение всей жизни вашей программы. В то время как метка в модальном диалоговом окне (open, close, open, close) может фактически иметь избыточное удержание и утечку за цикл. И это потому, что (опять же спекуляция) каждое закрытое диалоговое окно сериализуется в файловую систему и таким образом сохраняется положение и размер x,y, а также его подвиды и т. д. И затем десериализовать ... на следующем сеансе open (против того, чтобы сказать minimiz или hidden.)