У меня есть UIView viewForRootVc
, который является объявленным свойством для подкласса UIView NewView
. NewView
несет ответственность за инициализацию viewForRootVc
, но затем подкласс NewViewSubClass
устанавливает цвет фона. Как только все это будет сделано, контроллер корневого представления RootVc
добавляет viewForRootVc
в качестве подпредставления к своему представлению.
Но это не работает. viewForRootVc
фактически не добавляется.
Однако, это ДЕЙСТВИТЕЛЬНО работает, если я делаю одну из следующих трех вещей (имейте в виду, что я использую ARC):
- Вместо того, чтобы устанавливать цвет фона
viewForRootVc
в NewViewSubClass
, я установил его в NewView
. И затем вместо инициализации экземпляра NewViewSubClass
я просто инициализирую экземпляр NewView
.
- При инициализации
viewForRootVc
в NewView
я вызываю установщик (то есть self.viewForRootVc), а не просто использую прямое присваивание.
- Список
viewForRootVc
в виде ивара в заголовочном файле NewView
.
Я не понимаю, почему любая из этих трех вещей необходима.
Вот код, который НЕ работает:
RootVc.m
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
NewView *newView = [[NewViewSubClass alloc] initWithFrame:CGRectMake(0, 0, 300, 300)];
//logs 0.00000, 0.00000
NSLog(@"%f, %f",newView.viewForRootVc.frame.size.width, newView.viewForRootVc.frame.size.height);
[self.view addSubview:newView.viewForRootVc];
//logs 0
NSLog(@"subviews: %i",[self.view.subviews count]);
}
NewView.h
@property (nonatomic, retain) UIView *viewForRootVc;
NewView.m
@synthesize viewForRootVc;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
viewForRootVc = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];
}
return self;
}
NewViewSubClass.m
@synthesize viewForRootVc;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
viewForRootVc.backgroundColor = [UIColor greenColor];
}
return self;
}
Одна вещь, которую я заметил, заключается в том, что если я укажу viewForRootVc
в качестве ивара, мне не нужно помещать @synthesize viewForRootVc;
в файл реализации NewViewSubClass
.
Я всегда понимал объявленные свойства для эффективного достижения следующего:
- Разрешить другим объектам доступ к ним.
- Позволяет при необходимости вызывать сеттер.
- Если не использовать ARC, вызов установщика автоматически сохранит свойство, если вы указали
retain
в объявлении свойства.
- В ARC автоматически создается ivar для любых объявленных свойств.
Но ясно, что есть нечто большее, чем это. Я не уверен, что это проблема с областью действия, или если мой нерабочий код, приведенный выше, в итоге создает две разные версии viewForRootVc
- возможно, ту, которая имеет правильный кадр, как указано в методе NewView
init
и тот, который имеет правильный цвет фона, как указано в методе NewViewSubClass
init
, но ни тот, ни другой не имеют ни правильной рамки, ни цвета.
Я очень надеюсь, что кто-то сможет раз и навсегда прояснить для меня последствия объявленных свойств по сравнению с ivars, а также вызвать установщик, чтобы установить объявленное свойство и присвоить ему значение напрямую.