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] {
}
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] {
....
}
Update
A forced downcast is now required using the !
operator, so the code above should be:
let families = p.fathers.array as! [Family]
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With