使用Getters和Setter来修改没有Swift中Subclassing的值

时间:2014-06-05 05:33:15

标签: swift

我们说我有一个类,当我设置它的属性时,我希望它使用类似.fileType的文件类型附加该属性:

class File {
    var fileName: String {
    get {
        return self.fileName
    }
    set {
        self.fileName = fileName + ".fileType"
    }
    }
}

我尝试使用这样的:

let newFile = File()
newFile.fileName = "My File"

不幸的是,变量从未设置:

Checkpoints

我有两种可能的解决方法。

选项1:设置后观察值

class File {
    var fileName: String = "" {
    didSet {
        self.fileName += ".fileType"
    }
    }
}

let file = File()
file.fileName = "SomeName" // SomeName.fileType

但是有了这个,我必须等到这个值已经设置好才能修改它。对于这个特殊的例子,它并没有太大的区别;但是,我希望能够避免这种情况。

选项2:子类

此解决方案基于示例here.搜索' speedLimitedCar'

class File {
    var fileName = ""
}

class SubFile: File {

    override var fileName: String {
    get {
        return super.fileName
    }
    set {
        super.fileName = newValue + ".fileType"
    }
    }
}

let subfile = SubFile()
subfile.fileName = "Hello" // Hello.fileType

问题

我还可以创建一个辅助属性来存储值并在fileName的getter / setter中访问它,但有没有办法避免所有这些并直接在其getter / setter中修改属性? / p>

1 个答案:

答案 0 :(得分:11)

如果您使用setget,则必须计算该属性。它没有实际的存储空间。

此代码定义用于保存数据的var和用于处理访问的计算var。这类似于你在Objective-C中所拥有的(除了在Objective-C中你可以通过将它变为私有来“隐藏”实际变量,或者最近,将它合成为标题中从未提及过的变量)。

class File {
    // this stores the actual data, do not access it directly, consider it private
    var theFileName: String = ""

    // this is the real interface
    var fileName: String {
        get {
            return self.theFileName
        }
        set(name) {
            self.theFileName = name + ".fileType"
        }
    }
}

你也可以这样写set

set {
    self.theFileName = newValue + ".fileType"
}

如果省略newValue的参数声明,则set是默认名称。

但你可能想要做的就是你已经做过的事情(并且由于不明原因被拒绝):

var fileName: String = "" {
    didSet {
        self.fileName += ".fileType"
    }
}

这是正确的方法。

请注意“我必须等到该值已经设置才能修改它。”不是真的。它看起来像,但编译器可以很好地优化代码(可能会)。