当数组中添加/删除元素时通知

11

我希望在数组中添加/删除元素时得到通知。如果我们不是在谈论数组,例如当字符串改变时得到通知,那么在 Swift 中有一个很好的解决方案:

private var privateWord: String?
var word: String? {
    get {
        return privateWord
    }
    set {
        if newValue != "" {
            notifyThatWordIsChanged()
        } else {
            notifyThatWordIsEmpty()
        }
        privateWord = newValue
    }
}

当我向数组添加/删除元素时,我们可以实现类似的结果吗?

1个回答

6
你可以创建类/结构体作为代理,其接口与数组相同,将标准数组存储在后台,并代表存储的数组进行操作。下面是一个小例子:
struct ArrayProxy<T> {
    var array: [T] = []

    mutating func append(newElement: T) {
        self.array.append(newElement)
        print("Element added")
    }

    mutating func removeAtIndex(index: Int) {
        print("Removed object \(self.array[index]) at index \(index)")
        self.array.removeAtIndex(index)
    }

    subscript(index: Int) -> T {
        set {
            print("Set object from \(self.array[index]) to \(newValue) at index \(index)")
            self.array[index] = newValue
        }
        get {
            return self.array[index]
        }
    }
}

var a = ArrayProxy<Int>()
a.append(1)

这是一个不错的解决方法 - 但必须考虑到除非手动以类似的方式包装,否则所有其他数组方法(如map、sort等)和属性都不可用。 - Antonio
1
@Antonio 但我觉得访问底层数组很容易。a.array = a.array.map { ... } - Kirsteins
是的,我只是想指出它不是一个真正的“Array”,也不像一个“Array”(这意味着您不能将其传递给期望数组实例的函数)。我的话并不是批评,只是澄清一下。这个想法很好,但当然它并不是所有情况的解决方案。 - Antonio
1
如此厌烦子类化。为什么我们不能只使用观察? - devios1
@Antonio 是的,你可能希望它实现并转发所有 MutableCollectionRandomAccessCollectionRangeReplaceableCollectionExpressibleByArrayLiteral 方法,以便它可以像任何其他集合一样使用(包括 .map 等方法)。 - Slipp D. Thompson
@devios: 有点痛苦,但它是一个单一的实用类,可以无限重复使用。尤其是如果你的ArrayProxy.init()实现能够接受 willSet:(Int,T)->()?didSet:(Int,T)->()? 闭包。 - Slipp D. Thompson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接