Swift NSSet y CoreData

Estoy intentando mover una aplicación C & CoreData objetiva a Swift e iOS y golpear una panetworking de ladrillo con la iteración a través de los objects NSSet:

Xcode ha generado estas classs:

class Response: NSManagedObject { @NSManaged var responseText: String @NSManaged var score: NSNumber @NSManaged var answers: NSSet @NSManaged var question: Question } class Question: NSManagedObject { @NSManaged var questionText: String @NSManaged var questionType: String @NSManaged var qualifier: Qualifier @NSManaged var responses: NSSet } 

entonces en la class 3 estoy agregando un método que necesita para iterar a través de un NSSet ..

 class Answer: NSManagedObject { @NSManaged var evaluation: Evaluation @NSManaged var response: Response func scoreGap() -> Int { var max = 0 for aresponse in self.response.question.responses { // this next line throws an error var scoreVal = aresponse.score.integerValue if scoreVal > max { max = scoreVal } } return max - self.response.score.integerValue } } 

La línea después del comentario anterior da error "AnyObject no tiene un miembro llamado puntuación"

El método Objective-C se ve así y funciona bien:

 // returns the gap between the score of this answer and the max score -(NSNumber *)scoreGap { long max = 0; for(Response *aresponse in self.response.question.responses) { if(aresponse.score.longValue > max) max = aresponse.score.longValue; } max = max - self.response.score.longValue; return @(max); } 

Este es el tercer día de Swift, así que me puede estar perdiendo algo realmente obvio … ¡pero en este momento realmente no lo entiendo!

 for aresponse in self.response.question.responses { // this next line throws an error var scoreVal = aresponse.score.integerValue 

El problema es que for aresponse in ... responses es iterating a través de un NSSet. Swift no sabe lo que está en el NSSet, por lo que trata cada valor aresponse como un AnyObject, que no tiene properties. Por lo tanto, el comstackdor se queja cuando intenta get la propiedad de score de una aresponse .

Usted , por otro lado, sabe que cada valor aresponse una respuesta. Entonces debes decirle a Swift esto, lanzando (con as ). Tenga en count que, de hecho, estaba haciendo eso en su código de Objective-C:

 for(Response *aresponse in self.response.question.responses) 

Pero has olvidado hacer lo mismo en Swift. Puedes hacerlo de varias maneras; Por ejemplo, podrías escribir este tipo de cosas:

 for aresponse in self.response.question.responses { var scoreVal = (aresponse as Response).score.integerValue 

Eso nos lleva más allá del comstackdor, que ahora comparte nuestro conocimiento de lo que realmente es esta variable.

Una vez que te acostumbres a esto, estarás besando el suelo en el que Swift camina. Durante todo este time, en Objective-C, estabas haciendo suposiciones sobre qué tipo de object tenías, pero en realidad lo que tenías era un id y el comstackdor te dejaba enviar cualquier post, y así, a menudo crash con "selector no reconocido". En Swift, un locking de "selector no reconocido" es básicamente imposible porque el tipo de todo está especificado y el comstackdor no le permitirá enviar un post inapropiado a un object en primer lugar.

De hecho, he descubierto algo que podría ser útil. A partir de la versión Xcode 7.2 y Swift 2.0, la siguiente statement funciona:

 @NSManaged var responses: Set<Response> 

Creo que podría estar relacionado con el hecho de que Swift automáticamente bridges entre NSSet y NSArray. No he encontrado esto documentado pero está funcionando para mí y agradecería que alguien lo confirme.