如何使用XCode 6.3 Beta2从Swift中的SuperClass覆盖setter?

con*_*ile 16 inheritance overriding ios uicollectionviewcell swift

我的SuerClass UICollectionViewCell有一个属性:

var selected: Bool
Run Code Online (Sandbox Code Playgroud)

我的班级是

MyClass : UICollectionViewCell {

  func setSelected(selected: Bool) { 
    super.selected = selected
    // do something
 }

}
Run Code Online (Sandbox Code Playgroud)

前者在XCode 6.2中运行良好,但在XCode 6.3Beta2中它引发了一个错误:

Method 'setSelected' with Objective-C selector 'setSelected:' conflicts with setter for 'selected' from superclass 'UICollectionViewCell' with the same Objective-C selector
Run Code Online (Sandbox Code Playgroud)

如何解决这个问题与XCode 6.3 beta2一起使用?

编辑:我也试过了

  override func setSelected(selected: Bool) { 
    super.selected = selected
    // do something
 }
Run Code Online (Sandbox Code Playgroud)

这导致错误:

var selected: Bool
Run Code Online (Sandbox Code Playgroud)

nhg*_*rif 42

如果我们想要它selected在设置属性后执行一些额外的功能,我们可以简单地覆盖以添加属性观察者:

override var selected: Bool {
    didSet {
        if self.selected {
            // do something
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我们关心以前的价值selected是什么,我们可以通过oldValue以下方式访问它:

override var isSelected: Bool {
    didSet {
        if self.isSelected {
            // do something
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

并且不要忘记,willSet如果我们需要在值更改之前执行某些操作,我们也可以使用它们.


我很好奇当我们有一个很大的类层次结构,每个类都添加自己的东西willSetdidSet属性观察器时会发生什么,所以我创建了以下测试:

didSet {
    if self.selected == oldValue {
        return
    }
    // do something
}
Run Code Online (Sandbox Code Playgroud)

现在,如果我们创建一个对象ClassC并设置其foo属性:

didSet {
    if self.isSelected == oldValue {
        return
    }
    // do something
}
Run Code Online (Sandbox Code Playgroud)

我们得到以下输出:

class ClassA {
    var _foo: Int = 0
    var foo: Int {
        set(newValue) {
            println("Class A setting foo")
            self._foo = newValue
        }
        get {
            return self._foo
        }
    }
}

class ClassB: ClassA {
    override var foo: Int {
        willSet {
            println("Class B will set foo")
        }
        didSet {
            println("Class B did set foo")
        }
    }
}

class ClassC: ClassB {
    override var foo: Int {
        willSet {
            println("Class C will set foo")
        }
        didSet {
            println("Class C did set foo")
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

因此,重要的是要注意一些事情......

  • 子类其父类之前willSet被调用.willSet
  • 子类didSet其父类之后调用的didSet.
  • 为了添加属性观察器而创建覆盖不会替换父类中的任何属性观察者.

前两点有点意义.实际上,这使得财产观察者更具吸引力.实际上,斯威夫特以适当的方式强迫我们的手上下层,并很好地将它分成两个独立的方法.Swift还阻止我们(我相信)覆盖父类的属性,但仍然让我们观察对该属性的更改 - 这比Objective-C的方法要好得多.

但第三点可能是最重要的.要小心 - 你可以很容易地陷入巨大的层面didSetwillSet代码中,这会减慢应该是一个非常快速的过程:设置属性的值.