2014-02-13 4 views
0

Раньше я создавал свои представления с помощью интерфейса-строителя.programatiically create views сильные свойства

При создании представлений с раскадными досками или наконечниками я бы подключил свои розетки. Я понимаю, что выходы создают прочную связь со свойствами на представлении.

Если я создаю представления программно, должны ли мои свойства быть сильными?

.h

@interface LoginViewController : UIViewController <UITextFieldDelegate> 

@property (nonatomic, strong) UIView *loginView; 

@property (nonatomic, strong) UITextField *usernameTextField; 
@property (nonatomic, strong) UITextField *passwordTextField; 

@property (nonatomic, strong) UIButton *signInButton; 

@end 

.m

@interface LoginViewController() 

@end 

@implementation LoginViewController 

- (void)initViewsAndLayout 
{ 
    _loginView = [[UIView alloc] init]; 
    _loginView.frame = self.view.bounds; 
    [self.view addSubview:_loginView]; 

    //... 
} 
@end 

ответ

3

Несколько вещей:

  1. Ваш код не использует свойства, определенные
  2. Не ставить частная собственность в .h файле
  3. Не сказать, что ваш класс соответствует протоколу UITextFieldDelegate в файле .h

Что касается, должны ли свойства быть strong или weakstrong Я предпочитаю, но так как вы будете добавлять каждый из этих свойств (просмотры) на вид контроллера контроллера было бы неплохо сделать их weak, так как всегда будет ссылка на них, пока контроллер просмотра жив.

Ваш .h должен быть просто:

@interface LoginViewController : UIViewController 
@end 

Вашего .m должны быть (если вы хотите использовать свойство):

@interface LoginViewController() <UITextFieldDelegate> 

@property (nonatomic, strong) UIView *loginView; 
@property (nonatomic, strong) UITextField *usernameTextField; 
@property (nonatomic, strong) UITextField *passwordTextField; 
@property (nonatomic, strong) UIButton *signInButton; 

@end 

@implementation LoginViewController 

- (void)initViewsAndLayout 
{ 
    self.loginView = [[UIView alloc] init]; 
    self.loginView.frame = self.view.bounds; 
    [self.view addSubview:self.loginView]; 

    //... 
} 

@end 
+0

Благодарим за объяснение! – slik

1

При использовании сильного атрибута, то вы в основном записывая retain, как и в, вы хотите, чтобы Objective-C выделял память для свойства и удерживал ее до тех пор, пока она не будет выпущена.

Это все сильное средство.

Это необходимо, только если вы используете ARC (хотя вы все равно можете использовать сохранение в ARC). Если нет, используйте сохранение.

«Если я создаю представления программно, должны ли мои свойства быть сильными?»

Если это объекты, а не примитивы, то да.

1

Я рекомендую вам создавать свойства с сильным атрибутом, если вы хотите создать его вручную, чтобы не использовать xib или раскадровку.

Как ваш код в initViewsAndLayout, если вы всегда создаете подзаголовок и одновременно добавляете его к представлению viewcontroller одновременно в той же области метода, нет проблем, даже если вы используете слабый или присваивающий атрибут. addSubview увеличит счетчик ссылок подзаголовка. Но я не думаю, что это такая хорошая привычка, потому что все мы могли ошибиться.

Следовательно, вам лучше сделать свойство UIView с сильным атрибутом.

1

В качестве простого эмпирического правила,

  1. Любого вид всегда принадлежит (поддерживаются сильной ссылка) его надтаблицы, когда они добавляются к надтаблице.
  2. Вид на верхний уровень всегда принадлежит (поддерживается сильной ссылкой) его VC.

Теперь вид может быть добавлен к его надтаблице два различным способов,

  • Когда представление создаются из кода и добавляется к некоторой надтаблице с использованием addSubview: метода. (Это ваш вопрос).
  • Когда иерархия представлений загружается из файла nib. (Здесь также неявные addSubview: звонки создаются UIKit для создания иерархии), и, таким образом, субблоки сохраняются путем сильной ссылки на их соответствующие наблюдения.

Таким образом, в обоих случаях виды неявно сохраняются их супервизорами и, таким образом, никогда не будут удаляться до тех пор, пока/за исключением того, что вид верхнего уровня не будет удален сам по себе. Так объявляя strong свойства подобозрения накладывает другую собственность на подвидах:

  • неявной собственность его надтаблицей и
  • Явно собственность на имуществе.

Так что объявление объекта strong для подзаголовков не требуется, однако оно было создано (от nib/по коду).

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


PS:

При создании представления с раскадровкой или наконечниками я соединил бы мои розеток. Я понимаю, что выходы создают сильное соединение со свойствами на представлении.

Я обнаружил, что в вашем вопросе есть просто заблуждение. При создании представления из раскадровки/ниба, выходы не создают никакого так называемого соединения strong со свойствами. IBOutlet s описывает, как свойство загружает представление. В случае свойства выхода вид, на который указывает свойство, не имеет аналогов и загружен, если он еще не загружен. Тем не менее, его сохранение по-прежнему зависит от устройства доступа к объекту strong/weak.

+0

+1 Я думаю, что вы и я оба имели такую ​​же реакцию на эти более ранние ответы! – Rob

+0

@Rob Я думаю, вы правы :) –

1

Вы спросили:

Если я создаю взгляды программно должны мои свойства быть strong?

Две части Ответ:

  1. мнение контроллер должен поддерживать определенный strong ссылку на его вид сверху уровня.

    Если вы вообще не используете NIB или раскадровку и все программно программируете, представление корня создается в loadView и обычно хранится в retain/strong. UIViewController уже имеет свойство view, которое несет в себе семантику памяти retain, которая обычно используется. (Для получения дополнительной информации о программном созданных представлениях, смотрите раздел Creating a View Programmatically в управлении ресурсов в Списке контроллерах главы Руководства по программированию View Controller для прошивки)

    (Если вы не создаете вид корня в loadView и вместо этого создают экземпляр корневого представления с помощью NIB или раскадровки и только программно создают подзоны, не беспокойтесь об этом обсуждении, поскольку NIB/раскадровка позаботится обо всем этом для вас.)

  2. Для в подзонах, когда вы вызываете addSubview, представление сохраняется по его родительскому виду. Нет необходимости в том, чтобы контроллер вида также поддерживал ссылку strong. Вы можете, но это не нужно.

    На мой взгляд, представление принадлежит его подзонам, а не контроллеру вида. Если одно из этих подзонов удалено из родительского представления, я не думаю, что диспетчер представлений должен его сохранить, и это не похоже на хороший дизайн, который я должен запомнить для nil свойства в контроллере представления. Хуже того, если я удалю представление контейнера с вложенными подзонами, я не хочу, чтобы вручную отслеживать установку всех этих индивидуальных свойств в контроллере представления, который у меня есть, также nil.

    Не поймите меня неправильно: вы можете использовать strong с subviews, если хотите. Но я считаю неправильным подразумевать, что не рекомендуется использовать weak.

Смежные вопросы