Macos 如何对Swift结构使用Cocoa绑定

Macos 如何对Swift结构使用Cocoa绑定,macos,swift,struct,cocoa-bindings,Macos,Swift,Struct,Cocoa Bindings,我在学斯威夫特 这些天我主要在iOS上工作,但我目前正在为OSX做一个小项目 在OSX上,我喜欢使用Cocoa绑定将模型中的值链接到UI元素。这样可以节省大量的胶水代码 我正在编写一个程序,比较Swift和C/Objective-C的性能。我正在使用素数生成器作为测试项目 我已经创建了一个Swift结构ComputeSettings,它封装了在Swift和Objective-C中运行素数生成器的设置(和结果)。该结构如下所示: struct ComputeResults { var tota

我在学斯威夫特

这些天我主要在iOS上工作,但我目前正在为OSX做一个小项目

在OSX上,我喜欢使用Cocoa绑定将模型中的值链接到UI元素。这样可以节省大量的胶水代码

我正在编写一个程序,比较Swift和C/Objective-C的性能。我正在使用素数生成器作为测试项目

我已经创建了一个Swift结构
ComputeSettings
,它封装了在Swift和Objective-C中运行素数生成器的设置(和结果)。该结构如下所示:

struct ComputeResults
{
  var totalCalculated:  Int = 0
  var primesPerSecond:  Int = 0
  var totalTime:        NSTimeInterval = 0
}
struct ComputeSettings
{
  var totalToCalculate: Int = 10000000
  var swiftResults:     ComputeResults = ComputeResults()
  var objCResults:      ComputeResults = ComputeResults()
}
然后,我的视图控制器中有一个ComputeSettings类型的实例变量:

class ViewController: NSViewController
{
  var theComputeSettings = ComputeSettings()
  var foo: Int = 12
  //...
}
在我的UI中,我有一个文本字段,允许用户输入要计算的素数。在IB中,我选择字段,选择utilities区域中的bindings选项卡,然后打开values绑定。我绑定到我的
ViewController
类。我输入
self.computesettings.totalToCalculate的模型键路径

当我运行我的项目时,它会失败并出现异常:

无法设置(contentViewController)用户定义的已检查属性 打开(NSWindow):[addObserver: forKeyPath:@“computesettings.totalToCalculate”选项:256 已将上下文:0x0]发送到与KVC不兼容的对象 “组件设置”属性

相反,如果我绑定到虚拟属性
foo
(因此模型键路径被设置为
self.foo
),那么它可以正常工作。在这种情况下,我看到我的文本字段显示我的值12

是否有某种方法可以使用Swift结构并仍然让Cocoa绑定工作?我在谷歌上搜索了不少,但什么也没找到


我当然可以手动完成,并编写一堆粘合代码将我的值从结构安装到窗口的视图中,但我更愿意使用Cocoa绑定。这就是他们的目的

不能将Cocoa绑定与Swift结构一起使用

Cocoa绑定系统是在键值观察之上实现的,键值观察是通过创建一个子类来截获发送到被观察对象的
set:
消息来实现的。Swift结构不能有子类,也不一定使用消息或函数调用来设置结构字段,因此通常无法拦截Swift结构字段的设置


消息抱怨缺少KVC遵从性,因为键值编码定义了消息名称的
set:
(和
getter)约定。

Well poo。这似乎是一个严重的限制。是否可以在结构中的原语值和/或结构本身上实现类别,以映射swift didSet方法来调用兼容KVO的set方法?我正在编写500磅的胶水代码来读取/显示我的字段的值。Cocoa绑定是OSX开发中更好的东西之一。我真的更愿意使用它们,即使这意味着在前面做一些繁重的工作。为什么计算机结果需要是一个结构?它实际上是您正在分析的代码的一部分吗?它不必是结构。这似乎是表示数据的最干净的方式。我想我会将其更改为自定义数据对象,因为对象上的属性应该与KVO兼容,对吗?如果希望KVO工作,请使用
NSObject
的子类。事实上,这是正确的答案。KVO仅适用于属于
NSObject
子类的对象。