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

Programmatically create NSPopupButton and add items to list

我已经能够以编程方式创建 NSPopupButton 并将其添加到我的 window,并且我可以使用相同的方法将项目添加到列表,但我想弄清楚如何才能通过另一种方法向其中添加项目。

以下是我目前有效的方法:

// 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 中的代码放在我的初始化部分的顶部,但它甚至不会在那里创建弹出按钮。

您的代码有两个问题:

  1. 里面windowControllerDidLoadNib:

    您没有将新创建的按钮分配给您的 ivar,而是仅分配给一个函数局部变量(与您的 ivar 同名)。

  2. 为什么里面没有任何反应refreshDevices

    initwindowControllerDidLoadNib: 之前被调用,所以你的 ivar 是 nil(并且因为 1.)。向 nil 发送消息没有任何作用。

解法:

  1. windowControllerDidLoadNib: 中删除 NSPopUpButton * 这样您就可以将新按钮分配给您的 ivar 而不是某个函数局部变量。

  2. windowControllerDidLoadNib: 结束时调用 refreshDevices,或者在某个时候您知道 windowControllerDidLoadNib: 已被调用而您的按钮不是 nil


编辑:

你应该记住,当你从超级视图中删除按钮时,它可能会被释放,因为你在创建后释放了它。

当它被释放时,你的 button ivar 指向一个 invalid/deallocated 对象,在这种状态下使用会导致未定义的行为。

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

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