以编程方式创建NSPopupButton并将项添加到列表

时间:2015-07-05 22:06:34

标签: objective-c cocoa nspopupbutton

我已经能够以编程方式创建一个NSPopupButton并将其添加到我的窗口,我可以使用相同的方法将项添加到列表中,但我想知道如何从另一个方法添加项目方法

到目前为止,这是我的工作:

// in my .h file:
@interface AVRecorderDocument : NSDocument
{
    @private
    NSPopUpButton *button;   
}

@property (assign) IBOutlet NSWindow *mainWindow;
// in my .m file:
@implementation AVRecorderDocument
    @synthesize mainWindow;

    - (void)windowControllerDidLoadNib:(NSWindowController *) aController
    {
        NSView *superview = [mainWindow contentView];

        NSRect frame = NSMakeRect(10,10,149,22);
        NSPopUpButton *button = [[NSPopUpButton alloc]  initWithFrame:frame];

        [superview addSubview:button];
        [button release];
    }

    - (void)refreshDevices
    {
        // I'd like to add items to my popupbutton here:
        // [button addItemWithTitle: @"Item 1"];
    }

@end

在refreshDevices中我没有得到编译器错误,只是没有任何东西被添加到弹出按钮。方法refreshDevices从 - (id)init调用。我也尝试将windowControllerDidLoadNib中的代码放在我的init部分的顶部,但它甚至不会在那里创建弹出按钮。

1 个答案:

答案 0 :(得分:2)

您的代码存在两个问题:

  1. 内部windowControllerDidLoadNib:

    您不会将新创建的按钮分配给您的ivar,而只能分配给函数局部变量(与您的ivar同名)。

  2. 为什么refreshDevices

    内没有任何反应 在init之前调用

    windowControllerDidLoadNib:,因此您的ivar为nil(因为1)。向nil发送消息不会做任何事情。

  3. 解决方案:

    1. NSPopUpButton *移除windowControllerDidLoadNib:,以便将新按钮分配给您的ivar,而不是某个功能本地变量。

    2. refreshDevices结束时拨打windowControllerDidLoadNib:,或者在某个时刻致电windowControllerDidLoadNib:,并且您的按钮不是nil

    3. 修改

      您应该记住,从超级视图中删除按钮的那一刻,它可能已取消分配,因为您在创建后将其释放。

      当它被解除分配时,你的button ivar指向一个无效/解除分配的对象,当在这种状态下使用时会导致未定义的行为。

      我建议release dealloc内的按钮,这样您就可以确保在文档对象的整个生命周期内都有一个有效的对象。

      但是,我不知道您的确切用例可能需要这种设计。