如何将NSMutableOrderedSet转换为通用数组?

16

我有这个for循环,p是一个NSManagedObjectfathers是一个to-many关系,因此我需要将NSMutableOrderedSet强制转换为[Family],但它不起作用,为什么?

for f in p.fathers as [Family] {
}
输入图像描述

2个回答

39
您可以通过array属性获取集合的数组表示形式-然后可以将其向下转换为适当的类型并赋值给变量:
let families = p.fathers.array as [Family]

当然,您也可以直接在循环中使用它:

for f in p.fathers.array as [Family] {
    ....
}

更新

现在需要使用!运算符进行强制向下转换,因此上面的代码应该是:

let families = p.fathers.array as! [Family]

虽然 .array 仍然存在,但我无法将其转换为另一种类型的数组:Cannot convert value of type '[Any]' to type '[T]' in coercion - Mathieson
你必须进行强制转换,即 as! [Family] - Antonio

5

在这种情况下,应该使用Antonio提出的简单解决方案。我想进一步讨论一下。如果我们尝试在'for'循环中枚举'NSMutableOrderedSet'的实例,编译器会报错:

错误:类型“NSMutableOrderedSet”不符合协议“SequenceType”

当我们写

for element in sequence {
    // do something with element
}

编译器会将其重写成类似以下的形式:
var generator = sequence.generate()

while let element = generator.next() {
    // do something with element
}

'NS(可变)有序集合'没有'generate()'方法,即它不符合'SequenceType'协议。我们可以改变这个情况。首先,我们需要一个生成器:

public struct OrderedSetGenerator : GeneratorType {

    private let orderedSet: NSMutableOrderedSet

    public init(orderedSet: NSOrderedSet) {
        self.orderedSet = NSMutableOrderedSet(orderedSet: orderedSet)
    }

    mutating public func next() -> AnyObject? {
        if orderedSet.count > 0 {
            let first: AnyObject = orderedSet.objectAtIndex(0)
            orderedSet.removeObjectAtIndex(0)
            return first
        } else {
            return nil
        }
    }
}

现在我们可以使用该生成器使 'NSOrderedSet' 符合 'SequenceType'
extension NSOrderedSet : SequenceType {
    public func generate() -> OrderedSetGenerator {
        return OrderedSetGenerator(orderedSet: self)
    }
}

'NS(Mutable)OrderedSet'现在可以在'for'循环中使用:

let sequence = NSMutableOrderedSet(array: [2, 4, 6])

for element in sequence {
    println(element) // 2 4 6
}

我们可以进一步实现'CollectionType''MutableCollectionType'(仅适用于'NSMutableOrderedSet'),使得'NS(Mutable)OrderedSet'的行为类似于Swift标准库中的集合。

我不确定上述代码是否遵循最佳实践,因为我仍在努力理解所有这些协议的细节。


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