Swift 2,方法'setOn'与Objective-C selector 'setOn:'与setter for 'on发生冲突与相同的Objective-C selector

时间:2023-01-15 18:29:41

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)
        }
    }
}