为类型化数组创建swift数组扩展

时间:2015-04-13 12:36:21

标签: ios arrays swift

这个问题(Create swift array extension for typed arrays [duplicate])非常接近回答这个问题,但在这个问题中做的事情可能是通用的。

这个问题(How can I extend typed Arrays in Swift?)也接近但问题不同,因为这个例子没有限制扩展到特定类型的数组。

假设我有一个UIView数组。

[node, node1, node2]

我想在其中添加extension func,如:

[node, node1, node2].hideAll()

extension UIView {
    func hide() { self.hidden = true }
}

extension Array {
    func hideAll() {
        for node in self { (node as! UIView).hide() }
    }
}

除了包含hideAll()类型对象的数组外,我不希望访问UIView。我可以和我如何限制这个?

1 个答案:

答案 0 :(得分:1)

您可以尝试以下内容:

protocol ShyObject : AnyObject {
    var hidden: Bool { get set }
}

extension SequenceType where Generator.Element : ShyObject {
    func hideAll() { for e in self { e.hidden = true } }
    func showAll() { for e in self { e.hidden = false } }
}

import UIKit

extension UIView : ShyObject {}
// TODO: extend more shy types...

let nodes = Array(count: 5, repeatedValue: UIView())
nodes.hideAll()

如果您还特别需要hide()方法,则可以为所有ShyObject提供通用:

extension ShyObject {
    func hide() { hidden = true }
    func show() { hidden = false }
}

为没有hidden的类型实现一致性:

class MyClass {}

extension MyClass : ShyObject {
    var hidden: Bool {
        get { return /* true or */ false }
        set { /* hide me or show me */ }
    }
}

let myObjects = Array(count: 5, repeatedValue: MyClass())
myObjects.hideAll()

我们也可以拥有allHiddenallShown属性:

extension SequenceType where Generator.Element : ShyObject {
    var allShown: Bool { return !contains{ $0.hidden == true } }
    var allHidden: Bool { return !contains{ $0.hidden == false } }
}

extension MutableCollectionType where Generator.Element : ShyObject {
    var allShown: Bool {
        get { return !contains{ $0.hidden == true } }
        set { newValue ? showAll() : hideAll() }
    }
    var allHidden: Bool {
        get { return !contains{ $0.hidden == false } }
        set { newValue ? hideAll() : showAll() }
    }
}

var nodes = Array(count: 5, repeatedValue: UIView()) // note the `var` :(

nodes.allShown = false
nodes.allHidden // true (does not in itself require a mutable collection!)

...哪个有效,但它有一个主要的缺点,如果我们想使用一个setter,序列必须是可变的。这是因为所有带有setter的计算属性都被编译器假设为mutating,即使序列元素属于这里的引用类型......但是,我们至少可以只有getter allShownallHidden属性,但没有为其付出可变性。

请注意,正如@dfri在某一点上所评论的那样,这个答案比明确要求的问题更为通用。如果不需要,@ dfri建议:

protocol Hideable {
    func hide()
}

extension UIView : Hideable  {
    func hide() { self.hidden = true }
}

extension Array where Element: Hideable {
    func hideAll() { for e in self { e.hide() } }
}