gpt4 book ai didi

swift - 无法在 swift 中创建程序化 Cocoa 绑定(bind)

转载 作者:行者123 更新时间:2023-11-30 10:48:50 25 4
gpt4 key购买 nike

我正在使用 swift 开发 macOS 应用程序。我的应用程序中有一个可以启用或禁用的警报对象。我创建了一个从警报的启用属性到用户界面中的复选框的 Cocoa 绑定(bind)。为了验证绑定(bind)是否有效,我向警报启用状态的 didSet 属性观察器方法添加了一条打印语句,并且当复选框切换时该消息会打印出来。

我现在想编写一个单元测试,以确保在切换启用的属性时实际发生正确的操作,并且我在以编程方式在单元测试中创建一个绑定(bind)时遇到困难,该绑定(bind)将模仿在接口(interface)中创建的绑定(bind)所发生的情况生成器。

测试看起来像这样:

func testAlarmTogglesEnabledState() {
let alarm = Alarm()
let enabler = AlarmEnabler(alarm)

enabler.enable()

XCTAssertTrue(alarm.enabled)
}

测试实际上比这更复杂,因为警报实际上采取了一些操作来启用或禁用自身,但是,这希望能够从本质上说明正在发生的情况。

AlarmEnabled 类如下所示:

@objc private class AlarmEnabler: NSObject {
init(_ alarm: Alarm) {
super.init()
let name = NSBindingName(rawValue: "enabled")
bind(name, to: alarm, withKeyPath: "enabled", options: nil)
}

func enable() {
enabled = true
}

@objc dynamic var enabled = false
}

Alarm 类具有以下形式:

@objc class Alarm: NSObject {


@objc private(set) var enabled = true {
didSet {
print("Alarm's enabled state was set to \(enabled)")
}
}


}

测试运行时,didSet 属性观察器中的消息永远不会打印,因此编程绑定(bind)显然不起作用。

这是我尝试编写的一个 Playground ,它基本上完成了单元测试想要完成的任务:

import Cocoa

@objc class Alarm: NSObject, Codable {
init(_ enabled: Bool = true) {
self.enabled = enabled
}

@objc dynamic var enabled: Bool {
didSet {
print("Alarm's enabled state was set to \(enabled)")
}
}
}

@objc class AlarmEnabler: NSObject {
init(_ alarm: Alarm) {
self.alarm = alarm
super.init()
let name = NSBindingName(rawValue: #keyPath(AlarmEnabler.enabled))
bind(name, to: alarm, withKeyPath: #keyPath(Alarm.enabled), options: nil)
// bind(name, to: alarm, withKeyPath: #keyPath(AlarmEnabler.enabled), options: nil)
checkBox.bind(NSBindingName.value, to: alarm, withKeyPath: #keyPath(Alarm.enabled), options: nil)
}

deinit {

}

func enable() {
enabled = true
checkBox.state = .on
}

func disable() {
enabled = false
checkBox.state = .off
}

@objc func checkBoxToggled(_ sender: NSButton) {
}

let checkBox = NSButton(checkboxWithTitle: "", target: self, action: #selector(AlarmEnabler.checkBoxToggled))
@objc dynamic var enabled = false
let alarm: Alarm
}

let alarm = Alarm(false)
let enabler = AlarmEnabler(alarm)

enabler.enable()
enabler.disable()

它将警报正确绑定(bind)到 a,并尝试使用复选框来模拟用户界面中发生的情况。这些似乎都无法使属性发生变化。什么可以让 Playground 代码正常工作?

最佳答案

好的,感谢 Willeke,我能够创建一个有效的 Playground ,并且我还能够编写单元测试并使其通过。这是可以正常工作的 Playground 版本:

import Cocoa

@objc class Alarm: NSObject, Codable {
init(_ enabled: Bool = true) {
self.enabled = enabled
}

@objc private(set) var enabled: Bool {
didSet {
print("Alarm's enabled state was set to \(enabled)")
}
}
}

@objc class AlarmEnabler: NSObject {
init(_ alarm: Alarm) {
super.init()
checkBox.bind(NSBindingName.value, to: alarm, withKeyPath: #keyPath(Alarm.enabled), options: nil)
}

func enable() {
checkBox.state = .on
checkBox.sendAction(checkBox.action, to: checkBox.target)
}

func disable() {
checkBox.state = .off
checkBox.sendAction(checkBox.action, to: checkBox.target)
}

@objc func checkBoxToggled(_ sender: NSButton) {
}

let checkBox = NSButton(checkboxWithTitle: "", target: self, action: #selector(AlarmEnabler.checkBoxToggled))
}

let alarm = Alarm(false)
let enabler = AlarmEnabler(alarm)

enabler.enable()
enabler.disable()

关于swift - 无法在 swift 中创建程序化 Cocoa 绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55105944/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com