如何使用 Xcode 6.3 Beta2 覆盖 Swift 中超类的 setter?
How can I override a setter from a SuperClass in Swift with Xcode 6.3 Beta2?
我的 SuerClass 是 UICollectionViewCell
,它有一个 属性:
var selected: Bool
我的 class 是
MyClass : UICollectionViewCell {
func setSelected(selected: Bool) {
super.selected = selected
// do something
}
}
前者在 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
如何解决此问题以与 Xcode 6.3 beta2 一起使用?
编辑:我也尝试过:
override func setSelected(selected: Bool) {
super.selected = selected
// do something
}
这会导致错误:
Method does not override any method from its superclass
如果我们希望它在设置 selected
属性 之后做一些额外的功能,我们可以简单地重写以添加一个 属性 观察者:
override var selected: Bool {
didSet {
if self.selected {
// do something
}
}
}
Swift 5 的更新答案:
override var isSelected: Bool {
didSet {
if self.isSelected {
// do something
}
}
}
如果我们关心 selected
的先前值是什么,我们可以通过 oldValue
:
访问它
didSet {
if self.selected == oldValue {
return
}
// do something
}
Swift 5 的更新答案:
didSet {
if self.isSelected == oldValue {
return
}
// do something
}
别忘了,如果我们需要在更改值之前做一些事情,我们也可以使用 willSet
。
我很好奇当我们有一个很大的 classes 层次结构时会发生什么,每个人都在 willSet
和 didSet
属性 观察者中添加自己的东西,所以我创建了以下测试:
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")
}
}
}
现在,如果我们创建一个 ClassC
的 object 并设置它的 foo
属性:
var c: ClassC = ClassC()
c.foo = 42
我们得到以下输出:
Class C will set foo
Class B will set foo
Class A setting foo
Class B did set foo
Class C did set foo
因此,请务必注意以下几点...
- A child class 的
willSet
在 其 parent 的 willSet
之前被称为 。
- A child class 的
didSet
被称为 在 其 parent 的 didSet
之后。
- 为了添加 属性 观察者而创建覆盖 不会 替换 parent [=71= 中的任何 属性 观察者]es.
前两点有点道理。实际上,这让 属性 观察者更具吸引力。实际上,Swift 迫使我们的手以适当的方式在层次结构中上下移动,并将其很好地分成两个单独的方法。 Swift 也阻止我们(我相信)覆盖 parent class 的 属性,但仍然让我们观察到 属性 的变化——这个比Objective-C的方法好多了。
但第三点可能是最重要的。小心——您很容易陷入 didSet
和 willSet
代码的巨大层次结构中,这会减慢本来应该非常快速的过程:设置 属性 的值。
我的 SuerClass 是 UICollectionViewCell
,它有一个 属性:
var selected: Bool
我的 class 是
MyClass : UICollectionViewCell {
func setSelected(selected: Bool) {
super.selected = selected
// do something
}
}
前者在 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
如何解决此问题以与 Xcode 6.3 beta2 一起使用?
编辑:我也尝试过:
override func setSelected(selected: Bool) {
super.selected = selected
// do something
}
这会导致错误:
Method does not override any method from its superclass
如果我们希望它在设置 selected
属性 之后做一些额外的功能,我们可以简单地重写以添加一个 属性 观察者:
override var selected: Bool {
didSet {
if self.selected {
// do something
}
}
}
Swift 5 的更新答案:
override var isSelected: Bool {
didSet {
if self.isSelected {
// do something
}
}
}
如果我们关心 selected
的先前值是什么,我们可以通过 oldValue
:
didSet {
if self.selected == oldValue {
return
}
// do something
}
Swift 5 的更新答案:
didSet {
if self.isSelected == oldValue {
return
}
// do something
}
别忘了,如果我们需要在更改值之前做一些事情,我们也可以使用 willSet
。
我很好奇当我们有一个很大的 classes 层次结构时会发生什么,每个人都在 willSet
和 didSet
属性 观察者中添加自己的东西,所以我创建了以下测试:
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")
}
}
}
现在,如果我们创建一个 ClassC
的 object 并设置它的 foo
属性:
var c: ClassC = ClassC()
c.foo = 42
我们得到以下输出:
Class C will set foo
Class B will set foo
Class A setting foo
Class B did set foo
Class C did set foo
因此,请务必注意以下几点...
- A child class 的
willSet
在 其 parent 的willSet
之前被称为 。 - A child class 的
didSet
被称为 在 其 parent 的didSet
之后。 - 为了添加 属性 观察者而创建覆盖 不会 替换 parent [=71= 中的任何 属性 观察者]es.
前两点有点道理。实际上,这让 属性 观察者更具吸引力。实际上,Swift 迫使我们的手以适当的方式在层次结构中上下移动,并将其很好地分成两个单独的方法。 Swift 也阻止我们(我相信)覆盖 parent class 的 属性,但仍然让我们观察到 属性 的变化——这个比Objective-C的方法好多了。
但第三点可能是最重要的。小心——您很容易陷入 didSet
和 willSet
代码的巨大层次结构中,这会减慢本来应该非常快速的过程:设置 属性 的值。