【问题标题】:Can't figure out how to do this cocoa binding不知道怎么做这种可可绑定
【发布时间】:2012-01-17 23:13:43
【问题描述】:

我是一名 .net 开发人员,正在尝试学习如何在 Mac 上进行可可编程。我遇到了一个我似乎无法弄清楚或找不到答案的问题。

我创建了以下类:

  • ITObject - NSObject 的子类
  • ITPlayer - ITObject 的子类
  • ITEnemy - ITObject 的子类

在我的MainMenu.xib 文件中,我有一个包含以下控件的窗口:

  • NSArrayController - 链接到 App Delegate (itObjects)
  • NSTableView - 链接到 NSArrayController (arrangedObjects)
  • NSTextBox - 链接到同一个 NSArrayController (selection.player)

itObjects 是一个 NSMutableArray,我用它来包含任何 ITObject 类。 NSArrayController 设置为使用 ITObject 作为类。当我将 ITPlayer 添加到 itObjects 属性时,文本框不会读取 player 属性。

播放器属性是 ITPlayer 独有的。如果播放器属性不是类的一部分,我想在文本框中显示“N/A”,如果存在,我希望绑定显示该值。现在,它什么都不做。

关于对象的更多信息:

项目的代码如下所示:

@interface ITObject:NSObject <NSCoding>{ 
     int initiativeRoll, initiativeBonus, initiativeKicker;
}
@property int initiativeRoll, initiativeBonus, initiativeKicker;
@property (readonly) int initiativeTotal, initiativeCalc;
@end

这是 ITObject 的头文件(显然)。 ITEnemy 和 ITPlayer 是这样设置的(仅到目前为止)。

@interface ITPLayer:ITOjbect <NSCoding>{
     NSString *player;
}
@property (copy) NSString *player;
@end

ITPlayer 的 init 方法在实现文件中设置如下:

- (void)init{
     self = [super init]
     if (self){
          player = @"undefined";
     }
     return self;
}

还有一个 initWithCoder: 方法,但是我还没有使用过,所以我不认为这是可疑的。

非常感谢您的帮助!

【问题讨论】:

  • 你的描述很好。建议您包含代码,以便更轻松地帮助您调试。
  • 真的没有很多代码可以展示。大多数 ITObject 有几个属性,而 ITPlayer 和 ITEnemy 还有一些。我认为这与我对 Cocoa Bindings 缺乏了解有关……而且我不知道如何发布,哈哈。

标签: objective-c xcode cocoa cocoa-bindings


【解决方案1】:

我通常不向新的 Cocoa 开发人员推荐绑定,当然也不推荐复杂的绑定。不幸的是,绑定在配置有一点点错误时往往“什么也不做”。这使得它们很难调试,即使对于有经验的开发人员也是如此。在处理与NSUserDefaults 相关的大量配置选项时,绑定工作得很好,但是用它们来构建复杂的 UI 是一件很痛苦的事情。

另一方面,您的设置似乎很奇怪。 MainMenu.xib 的所有者几乎总是NSApplication。您应该将新的NSArrayController 拖到您的 XIB 上,而不是您正在做的事情,并按照您的描述将其连接起来,但不要使其成为文件所有者。

我希望您在日志中看到异常。可能是“NSArrayController不响应选择器setDelegate:”之类的。如果您看到这种情况,那是因为默认的 MainMenu nib 文件配置为将应用程序委托连接到文件所有者。


首先,引用Apple docs 中的一点点来加强关于绑定的观点:

使用 Cocoa 绑定填充基于视图的表视图被认为是一个高级主题。虽然它需要的代码要少得多(在某些情况下根本不需要代码),但如果您不熟悉该界面,则很难看到绑定。强烈建议您熟悉以编程方式使用基于视图的表格视图的技术,然后再继续使用 Cocoa 绑定。

我喜欢本节中的“严厉”一词。经过多年使用和不使用绑定的开发,我倾向于避免使用它们,除非在最简单的情况下(比如偏好面板,它们非常有用)。

如果没有绑定,您将按照Populating View-Based Table Views Programmatically 中的说明进行操作。基本上,您将实现 numberOfRowsInTableView: 和(假设 10.7+)tableView:viewForTableColumn:row:。对于每一行和每一列,您都返回一个包含所需数据的视图。这取自 iOS 的做事方式,非常好用且非常灵活。

如果您需要 10.7 之前的版本,那么事情会稍微复杂一些,但仍然比绑定更简单。见Populating Cell-Based Table Views。这使用NSCell 而不是NSView。如果您只需要一个显示类似字符串的数据的简单表格,那并不难。只需实现numberOfRowsInTableView:tableView:objectValueForTableColumn:row:。后者应该返回可以强制转换为字符串的内容。

如果您需要 10.7 之前的自定义 NSCell,请使用文档自行尝试,然后您可能会发布一些新问题。

【讨论】:

  • 你是对的,它不依赖于文件的所有者,而是链接到 AppDelegate 类的“App Delegate”对象。你能指出我在不使用绑定的情况下如何处理这个问题的方向吗?谢谢。
  • +1 用于避免新开发人员的绑定。当绑定是全新的(10.3?)时,我开始了 OS X 开发,它以简单性吸引了我,但正如你所说的最轻微的复杂性,一切都停止了,作为一个新开发人员,你无处可去(没有 SO in那些日子!)
  • 我在帖子中进行了更正,以表明 NSArrayController 已链接到我的 .xib 文件中的 App Delegate 对象。一切都很好,除了我无法绑定到子类属性,因为我有 NSArrayController 使用超类(ITOBject)。如果有人能指出我的教程或文章,或者可以描述另一种方法来做我想做的事,我将不胜感激。
  • 这很有帮助,但我认为我遇到的主要问题(在实现这个之后)是我不完全理解目标 c 中子类化的工作原理。在 .net 中,我可以这样做:ITObject myObj = new ITPlayer(); 这将转换为目标 c 为ITObject *myObj = [[ITPLayer alloc]init];,但是当我将消息发送到玩家的 myObj(如:[myObj player])字符串时,它什么也不做。这整个问题是由于我对目标 c 中子类化的工作方式缺乏了解而引起的吗?我明白我想做的事情应该奏效。谢谢
  • 我必须查看更多代码。你在这里显示的是正确的。 ObjC 中的子类化并没有什么特别之处,只是它只支持覆盖而不支持重载。 (您不能有两个具有相同名称但类型不同的参数的方法。)最可能的错误是在您的 init 方法中。
猜你喜欢
  • 2018-03-24
  • 1970-01-01
  • 2022-06-16
  • 2021-12-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-14
  • 2019-06-13
相关资源
最近更新 更多