为什么不能向 hopBill 发送消息:
首先,因为虽然你声明了它,但你从不初始化它。你有:
HopBill *hopBill;
[self.hopBill.aHopBill addObject: bHopAdditionAtInit];
它应该是:
HopBill *hopBill = [[HopBill alloc] init];
[hopBill.aHopBill addObject: bHopAdditionAtInit]; // “self” won’t work here
其次,您在 IBAction 方法 (doneHopBillSheet:) 中声明它,因此它是一个局部变量,只能在该方法中访问。如果 HopBill 保存了表的数据源缓存,它应该是实现 NSTableViewDataSourceProtocol 方法的控制器的属性。
在您的 HopBill 接口中,您将 aHopBill 数组声明为一个属性,并在 HopBill 的 init 方法中对其进行初始化(您还应该在 HopBill 的 dealloc 方法中将其释放)。您需要为控制器做同样的事情——它应该有一个 HopBill 实例作为属性,并且该实例应该在控制器的 init 方法中初始化。
如果你想让 HopBillController 管理 tableview,它的接口声明应该是这样的:
@interface HopBillSheetController : NSWindowController <NSTableViewDelegate, NSTableViewDataSource> {
…
}
然后,当然,你必须实现相关的 NSTableViewDelegate 和 NSTableViewDataSource 方法。
此外,控制器必须具有表视图本身的 IBOutlet 属性,并且在控制器的 awakeFromNib 方法中,它必须将自己分配为委托和数据源:
[self.tableview setDelegate:self];
[self.tableview setDataSource:self];
(self-dot 语法假定您已经为 tableview 设置了 @property 和 @synthesize 代码。)
将项目添加到表中的 IBAction 方法必须在该控制器类中,或者在具有作为控制器类实例的属性的类中。然后 IBAction 方法将访问 aHopBill 数组并可以将新对象添加到数组中,之后它将调用 [tableView reloadData],这将依次触发 tableview 协议方法并更新表。
现在,这意味着包含 tableview 的 xib 必须将控制器作为其文件的所有者。由于您使用的是 NSDocument,因此我怀疑您会将 tableview 插座放在 NSDocument 子类中。你会给那个文档子类一个属性,它是控制器的一个实例。IBAction 方法也将在 doc 子类中,因此它们可以访问控制器及其 HopBill 属性。或者,您可能只是将 doc 子类设置为控制器,而不是使用单独的 HopBillSheetController 类。我不确定 NSDocument 的东西。但是,请记住,IBAction 方法本身可以调用其他方法,只要它可以访问声明这些方法的类的实例。
Apple 有一个同时使用 tableview 委托和数据源协议方法的示例。转到此链接并下载示例代码:tableview 示例
它看起来像一个不错的应用程序。祝你好运。