1

在我的最后一个问题中,我询问了如何在 Swift 中为计算属性的下标编写 setter。我认为我的问题不够实质性,无法理解。对于一项小任务,给出的答案要么不正确,要么复杂。经过长时间的思考,我仍然认为也许一个更聪明的人可以提供一个更鼓舞人心的答案。

为了消除混乱,我的问题是Swift 中的数组下标是否有速记 setter 声明。因为 swift 中有一个数组的简写 setter 声明,但没有它的下标。

速记getter/setter 声明

var center: Point {
    get {
        let centerX = origin.x + (size.width / 2)
        let centerY = origin.y + (size.height / 2)
        return Point(x: centerX, y: centerY)
    }
    set {
        origin.x = newValue.x - (size.width / 2)
        origin.y = newValue.y - (size.height / 2)
    }
}

基本上,在一个 set 操作 foraction[i]将导致actionButton[i]更新的情况下。基本上有两种方法可以快速做到这一点。

第一个解决方案

func setActionAtIndex(index:Int, forValue newValue:SomeClass){
    action[index] = newValue
    self.updateActionButtonAtIndex(index)
}

上面的这个解决方案很容易理解,但是它需要一个函数,在一个类中需要两行代码。不完全是“斯威夫特”。

第二种解决方案

var action: [SomeClass] {
    subscript(index:Int){
        set(index:Int,newValue:SomeClass){
           action[index] = newValue
           //extra action to be performed 
           updateActionButtonAtIndex(index)

        }
        get{
           return action[index]
        }
    }
}

不用说,这是绝对错误的,而且这种解决方案是不存在的。

为什么是的?

Expected 'get', 'set', 'willSet', or 'didSet' keyword to start an accessor definition

因此,是否有类似于第二种解决方案但有效的解决方案?

4

2 回答 2

4

您不了解的是普通的二传手您正在寻找的速记。如果一个对象具有数组属性并且有人设置到该数组中,则调用 setter。

例如:

class Thing {
    var arr : [Int] = [1, 2, 3] {
        didSet {
            println("I saw that")
        }
    }
}

var t = Thing()
t.arr[1] = 100 // "I saw that"

因此,您所要做的就是didSet将新值与旧值进行比较,然后以您喜欢的方式响应更改。

于 2015-01-18T01:21:31.787 回答
1

我确实想到了另一种方法,但我不太喜欢它。使用扩展为 Array 的 setter 添加另一个下标 - 一个允许您提供回调的 setter。这种方法的问题是您必须记住提供回调!这将责任放在索引中的任何人身上,这可能不是您的想法。尽管如此,一旦配置好,它仍然具有简洁的优势 - 并且需要O(0)时间:

extension Array {
    subscript(ix:Int, f:(T,T,Int)->Void) -> T {
        set {
            let old = self[ix]
            self[ix] = newValue
            f(old,newValue,ix)
        }
        get {
            return self[ix]
        }
    }
}

class Thing {
    var arr : [Int] = [1, 2, 3]
    func f (oldv:Int, newv:Int, ix:Int) {
        println("changed \(oldv) to \(newv) at \(ix)")
    }
}

var t = Thing()
t.arr[1,t.f] = 100 // "changed 2 to 100 at 1"
于 2015-01-18T16:27:09.967 回答