Swift NSSet& CoreData

时间:2014-11-23 16:32:48

标签: ios core-data swift nsset

我正在努力推动一个客观的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的第三天,所以我很可能会遗漏一些非常明显的东西......但此刻我真的不明白!

2 个答案:

答案 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之间自动桥接的事实有关。我还没有找到这个记录,但它为我工作,如果有人确认,我将不胜感激。