使用NIB文件使用委托实例化UIView子类

时间:2011-02-28 19:47:43

标签: iphone cocoa ipad uiview nib

我有一个UIView子类,我想从NIB文件中实例化。我一直在使用这种方法来做到这一点:

UINib *nib = [UINib nibWithNibName:@"SSNodeToolsView" bundle:[NSBundle mainBundle]];
self = [[[nib instantiateWithOwner:self options:nil] objectAtIndex:0] retain];

......事实上,这会正确地创建对象并将所有内容联系起来。但是,该对象立即失去对其委托的访问权限。代表以通常的方式声明:

id delegate
@property (nonatomic, assign) id delegate
@synthesize delegate

......等等。但是,当对象从其nib加载时,委托会立即变为null并忽略任何为其赋值的尝试。奇怪的是,这不会导致崩溃。谁能告诉我为什么会这样?我更喜欢使用nib-loading方法,因为我的应用程序的这些元素可能会经常重新设计,使用笔尖最容易做到这一点。

-Ash

1 个答案:

答案 0 :(得分:7)

编辑:将关键点移至顶部。您不能同时创建一个对象并将其设置为同一个笔尖中的文件所有者。文件所有者需要是一个已经存在且已初始化的对象,其中包含nil outlet ivars,以便笔尖加载能够正确连接到所有者的出口。

委托对象也在笔尖中吗?如果没有任何东西保留它(你的财产是'分配')它可能会消失在下一个自动释放池排水管。代表是你笔尖的出口吗?加载笔尖后出口中的“零”值通常表示出口未正确连接。此外,您似乎正在使用尚未初始化的所有者对象(self)实例化nib?如果是这样,您的插座可能无法正确连接,因为如果所有者对象中的相应值为零,则仅连接插座。在将其用作加载笔尖的所有者之前,您应该拥有一个完全初始化的所有者对象。

这是我在我的一个项目中使用的“从nib加载此对象”初始化代码:

- (id)initWithFrame:(CGRect)frame 
{
    self = [super initWithFrame:frame];
    if (self) 
    {
        // Initialization code.
        //
        [[NSBundle mainBundle] loadNibNamed:@"ScoreView" owner:self options:nil];
        [self addSubview:self.view];
    }
    return self;
}

- (void) awakeFromNib
{
    [super awakeFromNib];

    [[NSBundle mainBundle] loadNibNamed:@"ScoreView" owner:self options:nil];
    [self addSubview:self.view];
}

使用nib具有内置的间接级别,您无法避免。您无法创建对象并同时将其用作文件所有者 - 所有者必须已存在并在笔尖加载时初始化(使用零输出)。

使用上面的代码,我可以从代码创建我的对象,也可以将其直接放到其他nib文件中 - 一个可重用的UIView组件。