Swift NSSet和CoreData

Ian*_*n33 6 core-data nsset ios swift

我正在尝试将一个客观的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
}
Run Code Online (Sandbox Code Playgroud)

然后在第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
    }
}
Run Code Online (Sandbox Code Playgroud)

上面注释后面的行给出了错误"AnyObject没有名为score的成员"

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);
}
Run Code Online (Sandbox Code Playgroud)

这是关于Swift的第三天,所以我可能会遗漏一些非常明显的东西......但此刻我真的不明白!

mat*_*att 12

for aresponse in self.response.question.responses {
    // this next line throws an error
    var scoreVal = aresponse.score.integerValue
Run Code Online (Sandbox Code Playgroud)

问题是for aresponse in ... responses迭代NSSet.斯威夫特不知道什么是该NSSet中,所以它把每个值aresponse作为AnyObject,它没有属性.因此,当您尝试获取score属性时,编译器会抱怨aresponse.

,在另一方面,知道每个值aresponse是响应.所以你需要通过cast(with )来告诉 Swift as.请注意,您实际上是在Objective-C代码中执行此操作:

for(Response *aresponse in self.response.question.responses)
Run Code Online (Sandbox Code Playgroud)

但你忘了在Swift做同样的事情.你可以用各种方式做到这一点; 例如,你可以写这种东西:

for aresponse in self.response.question.responses {
    var scoreVal = (aresponse as Response).score.integerValue
Run Code Online (Sandbox Code Playgroud)

这让我们超越了编译器,编译器现在分享我们对这个变量的真正含义.

一旦你习惯了这一点,你就会亲吻斯威夫特走过的地面.所有这一次,在Objective-C中,你在假设你拥有什么样的对象,但事实上你所拥有的是一个id而且编译器让你发送任何消息 - 所以,你经常会崩溃与"无法识别的选择器".在Swift中,"无法识别的选择器"崩溃基本上是不可能的,因为所有内容的类型都已指定,并且编译器不会让您首先向对象发送不适当的消息.