使用NIB文件实例化一个带有代理的UIView子类

6

我有一个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加载方法,因为我的应用程序中的这些元素很可能经常重新设计,使用nib会更容易。

-Ash

1个回答

7

编辑:将重点移到顶部。在同一个nib中,您不能同时创建对象并将其设置为文件所有者。文件所有者需要是一个已经存在并初始化的对象,其nil输出变量,以便nib加载正确地连接到所有者的输出变量。

委托对象也在nib中吗?如果没有任何东西保留它(您的属性是“assign”),则它可能会在下一个自动释放池排空时消失。委托是否是nib中的一个出口?在加载nib后,出口中的“nil”值通常表示出口未正确连接。此外,似乎您正在使用尚未初始化的所有者对象(self)实例化nib?如果是这样,因为只有在所有者对象中对应的值为nil时,出口才会连接,所以您的输出变量可能未正确连接。在使用它作为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];
}

使用nibs有一个内置的间接层,这是无法避免的。你不能创建一个对象并同时将其用作文件所有者--所有者必须在nib加载时已经存在并初始化(具有nil输出)。
使用上述代码,我可以从代码中创建我的对象或直接将其放入其他nib文件中--一个可重用的UIView组件。

啊哈,谢谢!原来如此。我正在改用更可靠的方法,将自定义视图从视图控制器中分离出来,并直接从其按钮发送 IBActions。这样我仍然可以使用 NIB。 - Ash
是的,那个可行,但你不必这样做。我在我的自定义UIView子类中使用上述代码,它们没有被从属于视图控制器。这是一个相当微妙的界限——视图控制器方法确实有一些好处,但感觉更加“笨重”。而且,除非你手动将这些调用转发到子视图控制器,否则你无法获得一些好处(viewWill/Did/Appear/Disapper)。 - Bogatyr
+1 很棒的回答!!特别是顶部的“关键点”内容。一旦你想到它,就很明显了,但像许多其他人一样,我肯定在看到你的答案之前没有想到它。感谢您节省了我的时间!! - jpswain
谢谢。是的,nib文件中固有的间接级别一开始非常棘手。 - Bogatyr
@Diziet 自然地,具体细节必须根据情况进行调整。我的代码片段并不是直接可用的,而是一个示例。我代码中的self.view是在.xib文件中定义的一个outlet。这个问题和我的答案的主要观点是:.xib文件中存在一定程度的间接性。再次强调:你不能同时创建一个对象并将其作为从.xib文件加载的File's Owner使用。关于这个问题的更完整的解释,请参见我在这里的回答:https://dev59.com/wm445IYBdhLWcg3wE2Je - Bogatyr
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接