当目标是不同的对象时不调用 NSButton 操作
NSButtion action not called when target is different object
我在视图控制器中有一个 NSButton,当单击它时,应该在另一个 class 的实例中调用一个方法(我在视图控制器中有那个实例)。但是,永远不会调用操作方法。
我的代码如下(简短)。请问有人可以解释这是为什么吗?
View Controller class 按钮:
class ViewController: NSViewController {
override func viewDidLoad() {
super.viewDidLoad()
let b:NSButton = NSButton(frame: NSRect(x: 150, y: 200, width: 30, height: 30))
self.view.addSubview(b)
let g = Global()
b.target = g
b.action = #selector(g.s)
}
}
Class 调用了 'Global' 我创建了一个实例,然后该按钮应该调用一个方法:
class Global:NSObject {
override init() {
super.init()
}
@objc dynamic func s() {
Swift.print("S ran")
}
}
谢谢
更新: 为了便于重现,我创建了一个 GitHub 存储库,以最简单的形式显示了该问题 here。
问题是当您单击按钮时,target
已设置为 nil
。这是因为g
被存储为局部变量而target
是弱属性,所以在viewDidLoad
执行完后,g
被释放,target
变为 nil
。因此,当您单击该按钮时,还没有可调用该操作的对象。
您需要在某处存储对目标的强引用。一种方法是将其作为实例变量存储在视图控制器上:
class ViewController: NSViewController {
let g = Global()
override func viewDidLoad() {
super.viewDidLoad()
let b:NSButton = NSButton(frame: NSRect(x: 150, y: 200, width: 30, height: 30))
self.view.addSubview(b)
b.target = g
b.action = #selector(g.s)
}
}
我在视图控制器中有一个 NSButton,当单击它时,应该在另一个 class 的实例中调用一个方法(我在视图控制器中有那个实例)。但是,永远不会调用操作方法。
我的代码如下(简短)。请问有人可以解释这是为什么吗?
View Controller class 按钮:
class ViewController: NSViewController {
override func viewDidLoad() {
super.viewDidLoad()
let b:NSButton = NSButton(frame: NSRect(x: 150, y: 200, width: 30, height: 30))
self.view.addSubview(b)
let g = Global()
b.target = g
b.action = #selector(g.s)
}
}
Class 调用了 'Global' 我创建了一个实例,然后该按钮应该调用一个方法:
class Global:NSObject {
override init() {
super.init()
}
@objc dynamic func s() {
Swift.print("S ran")
}
}
谢谢
更新: 为了便于重现,我创建了一个 GitHub 存储库,以最简单的形式显示了该问题 here。
问题是当您单击按钮时,target
已设置为 nil
。这是因为g
被存储为局部变量而target
是弱属性,所以在viewDidLoad
执行完后,g
被释放,target
变为 nil
。因此,当您单击该按钮时,还没有可调用该操作的对象。
您需要在某处存储对目标的强引用。一种方法是将其作为实例变量存储在视图控制器上:
class ViewController: NSViewController {
let g = Global()
override func viewDidLoad() {
super.viewDidLoad()
let b:NSButton = NSButton(frame: NSRect(x: 150, y: 200, width: 30, height: 30))
self.view.addSubview(b)
b.target = g
b.action = #selector(g.s)
}
}