如何对 Swift 结构使用 Cocoa 绑定
How to use Cocoa bindings against Swift structs
我正在学习Swift。
这些天我主要在 iOS 工作,但我目前正在为 OS X 做一个小项目。
在 OSX 上,我喜欢使用 Cocoa 绑定到 link 值,从我的模型到 UI 元素。它节省了编写大量胶水代码。
我正在编写一个程序来比较 Swift 和 C/Objective-C 的性能。我正在使用质数生成器作为测试项目。
我创建了一个 Swift 结构 ComputeSettings
,它封装了 运行 在 Swift 和 [=43] 中设置素数生成器的设置(和结果) =].该结构如下所示:
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 中,我 select 字段,选择实用程序区域中的绑定选项卡,然后打开值绑定。我绑定到我的 ViewController
class。我输入了 self.theComputeSettings.totalToCalculate
.
的模型关键路径
当我 运行 我的项目失败时出现异常:
Failed to set (contentViewController) user defined inspected property
on (NSWindow): [ addObserver:
forKeyPath:@"theComputeSettings.totalToCalculate" options:256
context:0x0] was sent to an object that is not KVC-compliant for the
"theComputeSettings" property.
相反,如果我绑定到虚拟 属性 foo
(因此模型键路径设置为 self.foo
),它会完美运行。在那种情况下,我看到我的文本字段显示我的值 12。
是否有某种方法可以使用 Swift 结构并仍然使 Cocoa 绑定起作用?我进行了大量谷歌搜索,但找不到任何东西。
我当然可以手动完成,并编写一堆胶水代码将我的值从我的结构安装到我的 window 的视图中,但我更愿意使用 Cocoa 绑定。这就是他们的目的。
您不能将 Cocoa 绑定与 Swift 结构一起使用。
Cocoa绑定系统是在Key-Value Observing之上实现的,Key-Value Observing是通过创建一个子类来拦截发送给被观察对象的set<Property>:
消息来实现的。 Swift 结构体不能有子类,也不一定使用消息或函数调用来设置结构体字段,所以通常没有办法拦截 Swift 结构体字段的设置。
该消息抱怨不符合 KVC,因为键值编码定义了消息名称的 set<Property>:
(和 <property>
getter)约定。
我正在学习Swift。
这些天我主要在 iOS 工作,但我目前正在为 OS X 做一个小项目。
在 OSX 上,我喜欢使用 Cocoa 绑定到 link 值,从我的模型到 UI 元素。它节省了编写大量胶水代码。
我正在编写一个程序来比较 Swift 和 C/Objective-C 的性能。我正在使用质数生成器作为测试项目。
我创建了一个 Swift 结构 ComputeSettings
,它封装了 运行 在 Swift 和 [=43] 中设置素数生成器的设置(和结果) =].该结构如下所示:
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 中,我 select 字段,选择实用程序区域中的绑定选项卡,然后打开值绑定。我绑定到我的 ViewController
class。我输入了 self.theComputeSettings.totalToCalculate
.
当我 运行 我的项目失败时出现异常:
Failed to set (contentViewController) user defined inspected property on (NSWindow): [ addObserver: forKeyPath:@"theComputeSettings.totalToCalculate" options:256 context:0x0] was sent to an object that is not KVC-compliant for the "theComputeSettings" property.
相反,如果我绑定到虚拟 属性 foo
(因此模型键路径设置为 self.foo
),它会完美运行。在那种情况下,我看到我的文本字段显示我的值 12。
是否有某种方法可以使用 Swift 结构并仍然使 Cocoa 绑定起作用?我进行了大量谷歌搜索,但找不到任何东西。
我当然可以手动完成,并编写一堆胶水代码将我的值从我的结构安装到我的 window 的视图中,但我更愿意使用 Cocoa 绑定。这就是他们的目的。
您不能将 Cocoa 绑定与 Swift 结构一起使用。
Cocoa绑定系统是在Key-Value Observing之上实现的,Key-Value Observing是通过创建一个子类来拦截发送给被观察对象的set<Property>:
消息来实现的。 Swift 结构体不能有子类,也不一定使用消息或函数调用来设置结构体字段,所以通常没有办法拦截 Swift 结构体字段的设置。
该消息抱怨不符合 KVC,因为键值编码定义了消息名称的 set<Property>:
(和 <property>
getter)约定。