How to covert NSMutableOrderedSet to generic array?

Deadly 提交于 2020-02-23 09:14:51

问题


I have this for loop, p is a NSManagedObject, fathers is a to-many relationship, so I need to cast NSMutableOrderedSet to [Family] but it does not work, why?

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


回答1:


You can obtain an array representation of the set via the array property - then you can downcast it to the proper type and assign to a variable:

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

but of course you can also use it directly in the loop:

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



回答2:


The simple solution by Antonio should be used in this case. I'd just like to discuss this a bit more. If we try to enumerate an instance of 'NSMutableOrderedSet' in a 'for' loop, the compiler will complain:

error: type 'NSMutableOrderedSet' does not conform to protocol 'SequenceType'

When we write

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

the compiler rewrites it into something like this:

var generator = sequence.generate()

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

'NS(Mutable)OrderedSet' doesn't have 'generate()' method i.e. it doesn't conform to the 'SequenceType' protocol. We can change that. First we need a generator:

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
        }
    }
}

Now we can use that generator to make 'NSOrderedSet' conform to 'SequenceType':

extension NSOrderedSet : SequenceType {
    public func generate() -> OrderedSetGenerator {
        return OrderedSetGenerator(orderedSet: self)
    }
}

'NS(Mutable)OrderedSet' can now be used in a 'for' loop:

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

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

We could further implement 'CollectionType' and 'MutableCollectionType' (the latter for 'NSMutableOrderedSet' only) to make 'NS(Mutable)OrderedSet' behave like Swift's standard library collections.

Not sure if the above code follows the best practises as I'm still trying to wrap my head around details of all these protocols.



来源:https://stackoverflow.com/questions/27076811/how-to-covert-nsmutableorderedset-to-generic-array

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!