我有一个包含@property
的视图控制器,它是UIView的自定义子类(我们可以称之为CanvasView)。这个CanvasView正在获得@synthesized
,但我想对它进行一些自定义初始化。我知道我需要在CanvasView上实现-(id)initWithFrame
并在那里进行自定义初始化,但是-(id)initWithFrame
没有被调用,或[self = [super initWithFrame:frame]
失败。 @synthesize
是否致电initWithFrame
?如何判断[super initWithFrame:frame]
是否失败?
注意:到目前为止,我已经以编程方式构建了界面,因此不应在此使用-(id)initWithCoder
或-(id)initWithNibNamed:bundle:
(我认为)。我猜这个问题的答案是开始使用nibs构建我的界面。
答案 0 :(得分:0)
@synthesize仅根据您在声明中指定的选项为您的属性的setter和getter生成代码。
如何初始化CanvasView实例?
答案 1 :(得分:0)
所有@synthesize
都会为您的媒体资源创建一个getter和setter。在使用之前,您仍需要初始化对象。
答案 2 :(得分:0)
如前所述,属性不会在属性后面创建对象。这是你必须在某个地方做的事情。最好的位置是initXXX:
初始值设定项之一,但有时您需要一些尚未出现的信息,例如关于窗口的信息等。然后您可以使用awakeFromNib
方法执行此操作。当笔尖完全加载时,它就会被“调用”。
另一种方法是延迟初始化。即使您使用@synthesize
,也没有什么可以阻止您编写自己的getProperty
(其中“属性”应该由属性的真实名称替换)方法。在那里你可以懒惰地初始化对象,即你不是在第一次需要它之前创建它。如果ivar为nil
,则为alloc
并初始化所需对象并将其存储在ivar中。然后你归还它。如果不是nil
,您只需返回ivar中的内容即可。如果属性是对象,则合成的setProperty:
仍然会保留新值并释放旧值。
延迟初始化示例:
- (MyObjType *) getFoo
{
if (!_foo)
{
_foo = [[MyObjType alloc] init... ];
_foo.something = 33;
_foo.garble = 1.234;
}
return [_foo autorelease];
}
答案 3 :(得分:-3)
如果您不打算使用笔尖,请尝试以下操作:
在视图控制器中:
- (void)loadView {
[super loadView];
//...
CanvasView *canvasView = [[CanvasView alloc] initWithFrame:CGRectMake(10,10,self.view.frame.size.width-20,self.view.frame.size.height-20)];
[self.view addSubview:canvasView];
[canvasView release];
//...
}
然后在你的CanvasView中(确保它扩展了UIView):
- (id)initWithFrame:(CGRect)frame {
if ((self = [super initWithFrame:frame])) {
// Perform custom init stuff...
}
return self;
}
希望这有帮助!