Cocoa编程,设置代理

7

我正在从iOS转向Cocoa,并尝试着完成我的前几个程序。我以为在我的表单中添加一个NSComboBox会很简单,而这一部分确实是简单的。我将<NSComboBoxDelegate, NSComboBoxDataSource>添加到了我的接口中,还有两个数据回调和通知器:

@interface spcAppDelegate : NSObject <NSApplicationDelegate,
                      NSComboBoxDelegate, NSComboBoxDataSource>

- (id)comboBox:(NSComboBox *)aComboBox objectValueForItemAtIndex:(NSInteger)index;
- (NSInteger)numberOfItemsInComboBox:(NSComboBox *)aComboBox;

- (void)comboBoxSelectionDidChange:(NSNotification *)notification;

@end

我将组合框(control)拖到应用程序委托(App Delegate)上(它是我简单默认应用程序中唯一的类),并连接代理(delegate)和数据源(data source),但这些事件都没有触发。我认为应用程序委托是正确的,但由于它没有触发,我也尝试了"文件所有者"和"应用程序"。我不认为那些会起作用,而且的确没起作用。
在Cocoa应用程序中,连接NSComboBox的代理/数据源的正确方式是什么?
谢谢!

当你说“它没有触发”时,你是如何测试的?在调试器中设置断点?使用NSLog? - user1118321
“没有触发”是指我添加了委托方法并在其中设置了断点,但未到达该断点。您可能认为两个数据方法未被调用是有道理的,但comboBoxSelectionDidChange应该是可达的。再次说明我的错误,因为我已经错误地连接了该事件。所以我实际上有两个问题,但主要修复是意识到有一个(新的?)复选框来指示我正在使用数据源。谢谢 :) - simusid
2个回答

15

如果您已经在spcAppDelegate.m文件中实现了这些方法,您可能想要再次检查Interface Builder中nib文件中的NSComboBox是否已选中Uses Data Source:

enter image description here

请注意,在我创建的一个快速测试项目中,默认情况下未设置该复选框。如果在没有设置该复选框的情况下运行,则启动应用程序时会将以下内容记录到控制台:

NSComboBox[2236:403] *** -[NSComboBox setDataSource:] should not be called when
          usesDataSource is set to NO
NSComboBox[2236:403] *** -[NSComboBoxCell setDataSource:] should not be called 
             when usesDataSource is set to NO

虽然NSComboBox类参考文档有些帮助,但当我刚开始学习时,我发现如果有附带的指南与该类链接,这更有助于理解如何在实践中使用该类。如果您查看Companion Guide中的NSComboBox类参考文档顶部,您将看到组合框编程主题

要设置使用数据源的组合框,您可以使用以下内容:

spcAppDelegate.h:

#import <Cocoa/Cocoa.h>

@interface spcAppDelegate : NSObject <NSApplicationDelegate,
                  NSComboBoxDelegate, NSComboBoxDataSource> {
    IBOutlet NSWindow            *window;
    IBOutlet NSComboBox            *comboBox;
    NSMutableArray                *comboBoxItems;
}

@property (assign) IBOutlet NSWindow *window;

@end

spcAppDelegate.m:

#import "spcAppDelegate.h"
@implementation spcAppDelegate
@synthesize window;
- (id)init {
    if ((self = [super init])) {
        comboBoxItems = [[NSMutableArray alloc] initWithArray:
               [@"Cocoa Programming setting the delegate"
                                        componentsSeparatedByString:@" "]];
    }
    return self;
}
- (void)dealloc {
    [comboBoxItems release];
    [super dealloc];
}
- (NSInteger)numberOfItemsInComboBox:(NSComboBox *)aComboBox {
    return [comboBoxItems count];
}
- (id)comboBox:(NSComboBox *)aComboBox objectValueForItemAtIndex:(NSInteger)index {
    if (aComboBox == comboBox) {
        return [comboBoxItems objectAtIndex:index];
    }
    return nil;
}
- (void)comboBoxSelectionDidChange:(NSNotification *)notification {
    NSLog(@"[%@ %@] value == %@", NSStringFromClass([self class]),
      NSStringFromSelector(_cmd), [comboBoxItems objectAtIndex:
        [(NSComboBox *)[notification object] indexOfSelectedItem]]);

}
@end

示例项目:http://github.com/NSGod/NSComboBox


1
非常感谢。它是“使用数据源”。我做得几乎没错 :) - simusid
感谢您提供的所有详细信息!非常有帮助。 - Marshall Moutenot
即使在OS 10.11和Xcode 8中,如果您不在Xib中勾选框,即使您以编程方式设置了comboBox.usesDataSource = true,它仍然无法正常工作,这真是令人难以置信的令人沮丧! - Nathaniel

0
昨天我遇到了类似的情况,直到我想起将文件所有者数据源连接到IB中的IBOutlet。

enter image description here


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