我怎样才能重写Swift中的SuperClass与XCode 6.3 Beta2的setter?
我的SuerClass是UICollectionViewCell
它有一个属性:
var selected: Bool
我的课是
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
属性设置之后做一些额外的function,我们可以简单地重写以添加属性观察者:
override var selected: Bool { didSet { if self.selected { // do something } } }
如果我们关心的是之前selected
值,我们可以通过oldValue
来访问它:
didSet { if self.selected == oldValue { return } // do something }
不要忘了,如果我们需要在值改变之前做一些事情,我们也可以使用willSet
。
我很好奇当我们有一个大的层次的类,每个在willSet
和didSet
属性观察者中添加他们自己的东西时会发生什么,所以我创build了以下testing:
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") } } }
现在,如果我们创build一个ClassC
的对象并设置它的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
所以,重要的是要注意一些事情…
- 在其父代的
willSet
之前调用一个子类的willSet
。 - 子类的
didSet
在父级的didSet
被调用。 - 为了添加属性观察器而创build重写不会replace父类中的任何属性观察器。
前两点有一定意义。 而事实上,这使得财产观察员更具吸引力。 有效地,斯威夫特用适当的方式强迫我们的手在上升和下降,很好地把它分成两个单独的方法。 Swift也阻止了我们(我相信)覆盖父类的属性,但是也让我们观察到对这个属性的改变 – 这比Objective-C的方法好得多。
但是第三点可能是最重要的。 要小心 – 你可以很容易地陷入一个大规模的didSet
并willSet
代码,这是一个非常快速的过程:设置一个属性的价值。