NSFastEnumeration in Swift

Estoy intentando convertir un proyecto de Objective-C en rápido, pero no puedo encontrar cómo usar NSFastEnumeration para un object de una class que se ajuste a NSFastEnumeration.

Aquí está el código en ObjC:

// get the decode results id<NSFastEnumeration> results = [info objectForKey: ZBarReaderControllerResults]; ZBarSymbol *symbol = nil; for(symbol in results) // just grab the first barcode break; 

hasta ahora he intentado encontrar la forma de hacer esto, pero este no parece funcionar, aquí está el código rápido:

 var results: ZBarSymbolSet = infoDictionary?.objectForKey(ZBarReaderControllerResults) as ZBarSymbolSet var symbol : ZBarSymbol? = nil; for symbol in results { //just grab first barcode break; } 

el error aparece para condición: "ZBarSymbolSet" no tiene un miembro llamado "Generator"

¿Qué estoy haciendo mal?

Aquí está la captura de pantalla introduzca la descripción de la imagen aquí

Después de un rato husmeando en torno a los files de marco rápido, finalmente encontré esta bonita class llamada NSFastGenerator . NSSet y amigos parecen estar usando el mismo Generator .

Para ZBarSymbolSet , esta es la forma en que lo extenderá para admitir for-in loops for-in :

 extension ZBarSymbolSet: SequenceType { public func generate() -> NSFastGenerator { return NSFastGenerator(self) } } 

Actualización: ¡ Parece que las extensiones de protocolo de Swift 2.0 arreglaron esto para nosotros!

Su class definida, ZBarSymbolSet necesita implementar la interfaz Swift SequenceType para que pueda usarse en for <identifier> in <sequence> syntax for <identifier> in <sequence> . La interfaz SequenceType es

 protocol SequenceType : _Sequence_Type { typealias Generator : GeneratorType func generate() -> Generator } 

y así ves la mención de Generator como se informó en tu post de error.

También en la syntax:

 for <identifier> in <sequence> { <statements> } 

el <identifer> está solo en scope para <statements> . Por lo tanto, su segundo uso del symbol en el if estará fuera del scope y un error. Un idioma apropiado sería:

 var symbolFound : ZBarSymbol? for symbol in result { symbolFound = symbol break } if symbolFound ... 

Si el curso, pero el time ZBarSymbolSet implementa SequenceType , también implementaría CollectionType con subscript y, por lo tanto, todo el código 'find the first element' sería var symbol = result[0]

 Step1: extension ZBarSymbolSet: SequenceType { public func generate() -> NSFastGenerator { return NSFastGenerator(self) } } Step2: var results: NSFastEnumeration = info.objectForKey(ZBarReaderControllerResults) as NSFastEnumeration var symbolFound : ZBarSymbol? for symbol in results as ZBarSymbolSet { symbolFound = symbol as? ZBarSymbol break } resultString = NSString(string: symbolFound!.data) 

Aquí está la respuesta de John Estropia para Swift 3:

 extension ZBarSymbolSet: Sequence { public typealias Iterator = NSFastEnumerationIterator public func makeIterator() -> NSFastEnumerationIterator { return NSFastEnumerationIterator(self) } } 

Entonces tu bucle for-in se vería así:

 for element in results { let symbol = element as! ZBarSymbol // ... } 

Esta respuesta podría mejorarse adoptando también el IteratorProtocol para que pueda especificar el tipo de elemento asociado como ZBarSymbol . No he descubierto cómo hacer esto todavía.

Además, si sabe que todos los objects en su ZBarSymbolSet son objects de ZBarSymbol (ya que ObjC no hace cumplir todos los objects que ZBarSymbol objects de ZBarSymbol ), puede hacer lo siguiente:

 extension ZBarSymbolSet { public struct ZBarSymbolSetIterator { public typealias Element = ZBarSymbol private let enumerator: NSFastEnumerationIterator init(_ symbols: ZBarSymbolSet) { self.enumerator = NSFastEnumerationIterator(symbols) } public mutating func next() -> ZBarSymbol { if let object = self.enumerator.next() { return object as? ZBarSymbol } else { return nil } } } public func makeIterator() -> ZBarSymbolSetIterator { return ZBarSymbolSetIterator(self) } } 

Ahora tu for-loop se verá así:

 for element in results { // element is a ZBarSymbol }