Swift 2, I have a class inherits from objc's UIView and it has 'on' variable, and related methods 'setOn:animated' and 'setOn:' like below:
Swift 2,我有一个类继承了objc的UIView,它有'on'变量,和相关的方法'setOn:animated'和'setOn:'如下:
public class AView: UIView {
var on: Bool = false
public func setOn(on: Bool, animated: Bool) {
self.on = on
// do something more about animating
}
public func setOn(on: Bool) {
setOn(on, animated: false)
}
And I got an error message: method 'setOn' with Objective-C selector 'setOn:' conflicts with setter for 'on' with the same Objective-C selector
我得到了一个错误消息:方法setOn和Objective-C selector 'setOn:'与setter for 'on发生冲突与相同Objective-C selector
I think willSet
or didSet
is not a solution because setOn:animated:
is called twice even if I add some guard conditions:
我认为willSet或didSet不是一个解决方案,因为setOn:animated:被调用两次,即使我添加了一些保护条件:
var on: Bool = false {
willSet {
if self.on != newValue {
setOn(self.on, animated: false)
}
}
}
....
....
let a = AView()
a.setOn(true, animated: true) // setOn:animated: is called twice
Is there a solution without changing a variable name and methods name?
有没有不改变变量名和方法名的解决方案?
Workaround: My solution is add extra internal variable and expose it with computed property. I don't like adding extra variable and definitely there will be a better solution.
解决方案:我的解决方案是添加额外的内部变量并使用computed property公开它。我不喜欢添加额外的变量,肯定会有更好的解决方案。
private var isOn: Bool = false
var on: Bool {
set(newOn) {
setOn(newOn, animated: false)
}
get {
return isOn
}
}
public func setOn(on: Bool, animated: Bool) {
self.isOn = on
// do something ...
}
2 个解决方案
#1
5
Similarly as in Compiler error: Method with Objective-C selector conflicts with previous declaration with the same Objective-C selector, you can also hide properties from the Objective-C runtime with @nonobjc
:
类似于编译器错误:使用Objective-C选择器的方法与使用相同的Objective-C选择器的先前声明相冲突,您还可以使用@nonobjc从Objective-C运行时隐藏属性:
public class AView: UIView {
@nonobjc var on: Bool = false
public func setOn(on: Bool, animated: Bool) {
self.on = on
// do something more about animating
}
public func setOn(on: Bool) {
setOn(on, animated: false)
}
}
which prevents a conflicting Objective-C setter from being auto-generated.
这可以防止自动生成冲突的Objective-C setter。
#2
0
Instead of willSet
you need to use didSet
你需要使用didSet而不是willSet
var on: Bool = false
{
didSet
{
if self.on != oldValue
{
setOn(self.on, animated: false)
}
}
}
#1
5
Similarly as in Compiler error: Method with Objective-C selector conflicts with previous declaration with the same Objective-C selector, you can also hide properties from the Objective-C runtime with @nonobjc
:
类似于编译器错误:使用Objective-C选择器的方法与使用相同的Objective-C选择器的先前声明相冲突,您还可以使用@nonobjc从Objective-C运行时隐藏属性:
public class AView: UIView {
@nonobjc var on: Bool = false
public func setOn(on: Bool, animated: Bool) {
self.on = on
// do something more about animating
}
public func setOn(on: Bool) {
setOn(on, animated: false)
}
}
which prevents a conflicting Objective-C setter from being auto-generated.
这可以防止自动生成冲突的Objective-C setter。
#2
0
Instead of willSet
you need to use didSet
你需要使用didSet而不是willSet
var on: Bool = false
{
didSet
{
if self.on != oldValue
{
setOn(self.on, animated: false)
}
}
}