我有一个 UIView viewForRootVc
,它是 UIView 子类的声明属性NewView
。初始化是NewView
的责任viewForRootVc
,但随后子类NewViewSubClass
设置其背景颜色。完成这一切后,根视图控制器RootVc
将viewForRootVc
作为子视图添加到其视图中。
但这不起作用。viewForRootVc
实际上并没有被添加。
但是,如果我执行以下三件事中的任何一项(请记住我使用的是 ARC),它确实有效:
- 我没有设置
viewForRootVc
in的背景颜色,而是将其设置为。然后,我不初始化 的实例,而是简单地初始化 的实例。NewViewSubClass
NewView
NewViewSubClass
NewView
- 在初始化
viewForRootVc
时NewView
,我调用setter(即self.viewForRootVc),而不是仅仅使用直接赋值。 viewForRootVc
在头文件中作为 ivar列出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]);
}
新视图.h
@property (nonatomic, retain) UIView *viewForRootVc;
新视图.m
@synthesize viewForRootVc;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
viewForRootVc = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];
}
return self;
}
新视图子类.m
@synthesize viewForRootVc;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
viewForRootVc.backgroundColor = [UIColor greenColor];
}
return self;
}
我注意到的一件事是,如果我指定为viewForRootVc
ivar,我不需要放入.@synthesize viewForRootVc;
NewViewSubClass
我一直理解声明的属性可以有效地实现以下目标:
- 允许其他对象访问它们。
- 允许在需要时调用 setter。
- 如果不使用 ARC,如果您
retain
在属性声明中指定,调用 setter 将自动保留该属性。 - 在 ARC 下,任何声明的属性都会自动生成一个 ivar。
但显然,它的意义远不止于此。我不确定这是否是范围问题,或者我上面的非工作代码是否最终创建了两个不同的版本——也许一个具有's方法viewForRootVc
中指定的正确框架,另一个具有正确的背景颜色在's方法中指定,但两者都没有正确的框架和颜色。NewView
init
NewViewSubClass
init
我非常希望有人可以一劳永逸地为我澄清声明的属性与 ivars 的含义,以及调用 setter 来设置声明的属性与直接为其赋值。