首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何用Xcode 6.3 SuperClass在Swift中用Xcode 6.3 Beta2覆盖setter?

如何用Xcode 6.3 SuperClass在Swift中用Xcode 6.3 Beta2覆盖setter?
EN

Stack Overflow用户
提问于 2015-03-14 13:02:50
回答 1查看 10.8K关注 0票数 16

我的SuerClass是UICollectionViewCell,它有一个属性:

代码语言:javascript
复制
var selected: Bool

我的课是

代码语言:javascript
复制
MyClass : UICollectionViewCell {

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

}

前者在Xcode 6.2中运行良好,但在Xcode 6.3Beta 2中则引发一个错误:

代码语言:javascript
复制
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?

编辑:我也尝试过:

代码语言:javascript
复制
  override func setSelected(selected: Bool) { 
    super.selected = selected
    // do something
 }

这将导致错误:

方法不覆盖其超类中的任何方法。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-03-14 13:13:30

如果我们希望它在设置selected属性之后执行一些额外的功能,我们可以简单地重写以添加属性观察者:

代码语言:javascript
复制
override var selected: Bool {
    didSet {
        if self.selected {
            // do something
        }
    }
}

Swift 5的最新答案:

代码语言:javascript
复制
override var isSelected: Bool {
    didSet {
        if self.isSelected {
            // do something
        }
    }
}

如果我们关心selected以前的值是什么,我们可以通过oldValue访问它。

代码语言:javascript
复制
didSet {
    if self.selected == oldValue {
        return
    }
    // do something
}

Swift 5的最新答案:

代码语言:javascript
复制
didSet {
    if self.isSelected == oldValue {
        return
    }
    // do something
}

别忘了,如果我们需要在值更改之前做一些事情,我们也可以使用willSet

我很好奇,当我们在willSetdidSet属性观察者中添加了各自的类的层次结构时,会发生什么,所以我创建了以下测试:

代码语言:javascript
复制
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的一个对象并设置它的foo属性:

代码语言:javascript
复制
var c: ClassC = ClassC()  
c.foo = 42

我们得到以下输出:

代码语言:javascript
复制
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命名为。
  • 为了添加属性观察者而创建覆盖时,不替换父类中的任何属性观察者。

前两点有点道理。事实上,这使得房地产观察家更有吸引力。有效地,斯威夫特迫使我们的手以适当的方式上上下下,并将其很好地分成两种不同的方法。Swift还阻止我们(我相信)重写父类的属性,但仍然允许我们观察对该属性的更改--这比Objective的方法要好得多。

但第三点可能是最重要的。要小心--您很容易陷入didSetwillSet代码的巨大继承之中,这会减缓应该非常快速的过程:设置属性的值。

票数 42
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29049238

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档