我正在努力推动一个客观的C& CoreData应用程序到Swift和iOS并通过迭代NSSet对象打砖墙:
Xcode已经生成了这些类:
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
}
然后在第3课我要添加一个需要迭代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
}
}
上面评论后面的行给出了错误" AnyObject没有名为score&#34的成员;
Objective-C方法看起来像这样,工作正常:
// 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);
}
这是关于Swift的第三天,所以我很可能会遗漏一些非常明显的东西......但此刻我真的不明白!
答案 0 :(得分:11)
for aresponse in self.response.question.responses {
// this next line throws an error
var scoreVal = aresponse.score.integerValue
问题是for aresponse in ... responses
正在迭代NSSet。 Swift不知道在 NSSet中是什么,因此它将每个值aresponse
视为AnyObject,它没有属性。因此,当您尝试获取score
的{{1}}属性时,编译器会抱怨。
你知道每个值aresponse
都是一个响应。所以你需要通过强制转换(使用aresponse
)来告诉 Swift。请注意,您实际上是在Objective-C代码中执行此操作:
as
但你忘了在Swift做同样的事情。你可以用各种方式做到这一点;例如,你可以写这样的东西:
for(Response *aresponse in self.response.question.responses)
这让我们超越了编译器,编译器现在分享我们对这个变量的真正含义。
一旦你习惯了这一点,你就会亲吻Swift走路的地面。所有这一次,在Objective-C中,你正在做假设关于你有什么样的对象,但事实上你所拥有的是for aresponse in self.response.question.responses {
var scoreVal = (aresponse as Response).score.integerValue
并且编译器允许你发送任何消息对它来说 - 所以,你经常会因为"无法识别的选择器而崩溃#34;在Swift中,一个"无法识别的选择器"崩溃基本上是不可能的,因为所有内容的类型都已指定,编译器不会让你首先向对象发送不适当的消息。
答案 1 :(得分:3)
实际上,我发现了一些可能有用的东西。从版本Xcode 7.2和Swift 2.0开始,以下声明有效:
@NSManaged var responses: Set<Response>
我认为这可能与Swift在NSSet和NSArray之间自动桥接的事实有关。我还没有找到这个记录,但它为我工作,如果有人确认,我将不胜感激。