Swift和CoreData,关系问题(NSSet) - [NSSet intersectsSet:]:set参数不是一个NSSet [英] Swift and CoreData, problems with relationship (NSSet) - [NSSet intersectsSet:]: set argument is not an NSSet

查看:749
本文介绍了Swift和CoreData,关系问题(NSSet) - [NSSet intersectsSet:]:set参数不是一个NSSet的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在试图在使用CoreData和Swift的关系中添加对象。我在亏损,我不明白为什么我的代码不工作。我试图添加一个事件到团队。我找不到接受的答案(应该工作)和我的代码(不工作)之间的差异。



Teams.swift:

  import Foundation 
import CoreData

class Teams:NSManagedObject {

@NSManaged var teamName :String
@NSManaged var matches:NSSet

}

扩展团队{

func addEventToTeam(event:Event){
//self.mutableSetValueForKeyPath (\"matches\").addObject (event)

var matchez:NSMutableSet

matchez = self.mutableSetValueForKey(matches)
matchez.addObject(event)


// var manyRelation = self.valueForKeyPath(matches)as NSMutableSet
//manyRelation.addObject(event)
}

func getTeamName() - > String {
return teamName
}


}

调用代码(从配置视图):

  import UIKit 
import CoreData

class DetailViewController:UIViewController,NSFetchedResultsControllerDelegate {

var managedObjectContext:NSManagedObjectContext? = nil

@IBOutlet weak var detailDescriptionLabel:UILabel!


var detailItem:AnyObject? {
didSet {
//更新视图。
self.configureView()
}
}

func configureView(){
//更新细节项的用户界面。
if let detail:Event =(self.detailItem as?Event){
// if let detail = AnyObject = self.detailItem {

if let label = self.detailDescriptionLabel {
label.text = detail.valueForKey(timeStamp)。description

self.insertNewObject(self);
label.text = String(detail.getNumberOfTeams())

//detail.getTeams()。
var hej:Array< Teams>
hej = detail.getTeams()

label.text =tjosan

for tmpTeam:hej中的团队{
label.text = label .text +,+ tmpTeam.getTeamName()
}


}
}

if true {


}


}

override func viewDidLoad(){
super.viewDidLoad()
/ /在加载视图之后执行任何其他设置,通常来自nib。
self.configureView()
}

override func didReceiveMemoryWarning(){
super.didReceiveMemoryWarning()
//处理任何可以重新创建。
}


var fetchedResultsController:NSFetchedResultsController {
if _fetchedResultsController!= nil {
return _fetchedResultsController!
}

let fetchRequest = NSFetchRequest()
//根据需要编辑实体名称。
let team = NSEntityDescription.entityForName(Teams,inManagedObjectContext:self.managedObjectContext)
fetchRequest.entity = team

//将批量大小设置为合适的数量。
fetchRequest.fetchBatchSize = 20

//根据需要编辑排序键。
让sortDescriptor = NSSortDescriptor(键:teamName,上升:FALSE)
让sortDescriptors = [sortDescriptor]

fetchRequest.sortDescriptors = [sortDescriptor]

//如果适当,编辑段名称键路径和缓存名称。
//节的名称键路径的nil表示没有节。
让aFetchedResultsController = NSFetchedResultsController(fetchRequest:fetchRequest,managedObjectContext:self.managedObjectContext,sectionNameKeyPath:无,cacheName:康师傅)
aFetchedResultsController.delegate =自
_fetchedResultsController = aFetchedResultsController

var error:NSError? = nil
if!_fetchedResultsController!.performFetch(& error){
//用代码替换此实现,以正确处理错误。
// abort()导致应用程序生成崩溃日志并终止。您不应在运送应用程序中使用此功能,但在开发过程中可能很有用。
// println(Unresolved error \(error),\(error.userInfo))
abort()
}

return _fetchedResultsController!
}
var _fetchedResultsController:NSFetchedResultsController? = nil



func insertNewObject(sender:AnyObject){
let context = self.fetchedResultsController.managedObjectContext
let team = self.fetchedResultsController.fetchRequest .entity
让newManagedObject = NSEntityDescription.insertNewObjectForEntityForName(team.name,inManagedObjectContext:context)as Teams

//如果适当,配置新的管理对象。
//通常你应该使用访问器方法,但是在这里使用KVC避免了需要为模板添加一个自定义类。
newManagedObject.setValue(Lagur Namnurk,forKey:teamName)

newManagedObject.addEventToTeam(self.detailItem as Event)


/ /保存上下文。
var error:NSError? = nil
if!context.save(& error){
//用代码替换此实现,以正确处理错误。
// abort()导致应用程序生成崩溃日志并终止。您不应在运送应用程序中使用此功能,但在开发过程中可能很有用。
// println(Unresolved error \(error),\(error.userInfo))
abort()
}
}
$ b b

}

错误讯息:



2014-08-13 18:38:46.651分数计算器2 [10538:829319] ***由于未捕获异常而终止应用程序NSInvalidArgumentException,原因: *** - [NSSet intersectsSet:]:set参数不是NSSet'
***第一次调用堆栈:

0 CoreFoundation 0x00000001028a53e5 __exceptionPreprocess + 165
1 libobjc .A.dylib 0x00000001043b8967 objc_exception_throw + 45
2的CoreFoundation 0x000000010280fc6c - [的NSSet intersectsSet:] + 940
3基础0x0000000102d0c4a6 NSKeyValueWillChangeBySetMutation + 156
4基金会0x0000000102c804fa NSKeyValueWillChange + 386
5基金会0x0000000102d0c3fb - [NSObject的(NSKeyValueObserverNotification)willChangeValueForKey:withSetMutation:usingObjects:] + 310
6 CoreData 0x00000001024178d7 - [NSManagedObject(_NSInternalMethods)_includeObject:intoPropertyWithKey:andIndex:] + 551
7 CoreData 0x0000000102418294 - [NSManagedObject(_NSInternalMethods) _maintainInverseRelationship:forProperty:forChange:发病:] + 276
8 CoreData 0x0000000102416ef2 - [NSManagedObject(_NSInternalMethods)_didChangeValue:forRelationship:命名为:withInverse:] + 562
9基金会0x0000000102c835d6 NSKeyValueNotifyObserver + 356
10基金会0x0000000102c827fd NSKeyValueDidChange + 466
11基金会0x0000000102d0c7ee - [NSObject的(NSKeyValueObserverNotification)didChangeValueForKey:withSetMutation:usingObjects:] + 118
12 CoreData 0x00000001024180b0 - [NSManagedObject didChangeValueForKey:withSetMutation:usingObjects:] + 80
13 CoreData 0x000000010242fa11 - [_ NSNotifyingWrapperMutableSet addObject:] + 161



编辑:几个澄清。团队和活动有多对多,无序的关系。

解决方案

Yesss!我找到了答案!



我在类Events.swift(关系的另一边)中创建了一个新函数。



我写了以下代码:

  import Foundation 
import CoreData

类事件:NSManagedObject {

@NSManaged var timeStamp:NSDate
@NSManaged var teams:NSSet

}

扩展事件{

func addTeamToEvent(team:Teams){
var teamz = self.mutableSetValueForKey(teams)
teamz.addObject team)
}

func getNumberOfTeams() - > Int {
return self.teams.count;
}

func getTeams() - > [Teams] {
var tmpsak:[Teams]
tmpsak = self.teams.allObjects as [Teams]
tmpsak = self.teams.allObjects as [Teams]

return tmpsak
}

}

是无关的。但是,将getTeams重命名为getTeamsAsArray会删除该问题。我猜CoreData,当填充关系的另一端,使用一个内置函数getTeams()(因为其他类称为Teams)。



感谢您的建议,我希望这对其他人有帮助!



在一个有些相关的注释,几年前发现了一个类似症状的错误(似乎仍然存在),它在使用有序多对多关系。


I've been trying to get my head around adding objects in relationships using CoreData and Swift. I am at a loss, I do not understand why my code does not work. I am trying to add an "Event" to a "Team". I can not find the difference between accepted answers (that should work), and my code (that does not).

Teams.swift:

import Foundation
import CoreData

class Teams: NSManagedObject {

    @NSManaged var teamName: String
    @NSManaged var matches: NSSet

}

extension Teams {

    func addEventToTeam(event:Event) {
        //self.mutableSetValueForKeyPath("matches").addObject(event)

        var matchez: NSMutableSet

        matchez = self.mutableSetValueForKey("matches")
        matchez.addObject(event)


        //var manyRelation = self.valueForKeyPath("matches") as NSMutableSet
        //manyRelation.addObject(event)
    }

    func getTeamName() -> String {
        return teamName
    }


}

Calling code (from configure view):

import UIKit
import CoreData

class DetailViewController: UIViewController, NSFetchedResultsControllerDelegate {

    var managedObjectContext: NSManagedObjectContext? = nil

    @IBOutlet weak var detailDescriptionLabel: UILabel!


    var detailItem: AnyObject? {
        didSet {
            // Update the view.
            self.configureView()
        }
    }

    func configureView() {
        // Update the user interface for the detail item.
        if let detail: Event = (self.detailItem as? Event) {
        //if let detail: AnyObject = self.detailItem {

            if let label = self.detailDescriptionLabel {
                label.text = detail.valueForKey("timeStamp").description

                self.insertNewObject(self);
                label.text = String(detail.getNumberOfTeams())

                //detail.getTeams().
                var hej: Array<Teams>
                hej = detail.getTeams()

                label.text = "tjosan"

                for tmpTeam : Teams in hej {
                    label.text = label.text + ", " + tmpTeam.getTeamName()
                }


            }
        }

        if true {


        }


    }

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        self.configureView()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


    var fetchedResultsController: NSFetchedResultsController {
        if _fetchedResultsController != nil {
            return _fetchedResultsController!
            }

            let fetchRequest = NSFetchRequest()
            // Edit the entity name as appropriate.
            let team = NSEntityDescription.entityForName("Teams", inManagedObjectContext: self.managedObjectContext)
            fetchRequest.entity = team

            // Set the batch size to a suitable number.
            fetchRequest.fetchBatchSize = 20

            // Edit the sort key as appropriate.
            let sortDescriptor = NSSortDescriptor(key: "teamName", ascending: false)
            let sortDescriptors = [sortDescriptor]

            fetchRequest.sortDescriptors = [sortDescriptor]

            // Edit the section name key path and cache name if appropriate.
            // nil for section name key path means "no sections".
            let aFetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: self.managedObjectContext, sectionNameKeyPath: nil, cacheName: "Master")
            aFetchedResultsController.delegate = self
            _fetchedResultsController = aFetchedResultsController

            var error: NSError? = nil
            if !_fetchedResultsController!.performFetch(&error) {
                // Replace this implementation with code to handle the error appropriately.
                // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
                //println("Unresolved error \(error), \(error.userInfo)")
                abort()
            }

            return _fetchedResultsController!
    }    
    var _fetchedResultsController: NSFetchedResultsController? = nil



    func insertNewObject(sender: AnyObject) {
        let context = self.fetchedResultsController.managedObjectContext
        let team = self.fetchedResultsController.fetchRequest.entity
        let newManagedObject = NSEntityDescription.insertNewObjectForEntityForName(team.name, inManagedObjectContext: context) as Teams

        // If appropriate, configure the new managed object.
        // Normally you should use accessor methods, but using KVC here avoids the need to add a custom class to the template.
        newManagedObject.setValue("Lagur Namnurk", forKey: "teamName")

        newManagedObject.addEventToTeam(self.detailItem as Event)


        // Save the context.
        var error: NSError? = nil
        if !context.save(&error) {
            // Replace this implementation with code to handle the error appropriately.
            // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
            //println("Unresolved error \(error), \(error.userInfo)")
            abort()
        }
    }



}

Error message:

2014-08-13 18:38:46.651 Score Calculator 2[10538:829319] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSSet intersectsSet:]: set argument is not an NSSet'
*** First throw call stack:
(
    0   CoreFoundation                      0x00000001028a53e5 __exceptionPreprocess + 165
    1   libobjc.A.dylib                     0x00000001043b8967 objc_exception_throw + 45
    2   CoreFoundation                      0x000000010280fc6c -[NSSet intersectsSet:] + 940
    3   Foundation                          0x0000000102d0c4a6 NSKeyValueWillChangeBySetMutation + 156
    4   Foundation                          0x0000000102c804fa NSKeyValueWillChange + 386
    5   Foundation                          0x0000000102d0c3fb -[NSObject(NSKeyValueObserverNotification) willChangeValueForKey:withSetMutation:usingObjects:] + 310
    6   CoreData                            0x00000001024178d7 -[NSManagedObject(_NSInternalMethods) _includeObject:intoPropertyWithKey:andIndex:] + 551
    7   CoreData                            0x0000000102418294 -[NSManagedObject(_NSInternalMethods) _maintainInverseRelationship:forProperty:forChange:onSet:] + 276
    8   CoreData                            0x0000000102416ef2 -[NSManagedObject(_NSInternalMethods) _didChangeValue:forRelationship:named:withInverse:] + 562
    9   Foundation                          0x0000000102c835d6 NSKeyValueNotifyObserver + 356
    10  Foundation                          0x0000000102c827fd NSKeyValueDidChange + 466
    11  Foundation                          0x0000000102d0c7ee -[NSObject(NSKeyValueObserverNotification) didChangeValueForKey:withSetMutation:usingObjects:] + 118
    12  CoreData                            0x00000001024180b0 -[NSManagedObject didChangeValueForKey:withSetMutation:usingObjects:] + 80
    13  CoreData                            0x000000010242fa11 -[_NSNotifyingWrapperMutableSet addObject:] + 161

edit: a couple of clarifications. Teams and Event have a multi-to-multi, unordered relationship.

解决方案

Yesss!! I found the answer!

I had created a new function in the class Events.swift (the other side of the relationship).

I had written the following code:

import Foundation
import CoreData

class Event: NSManagedObject {

    @NSManaged var timeStamp: NSDate
    @NSManaged var teams: NSSet

}

extension Event {

    func addTeamToEvent(team:Teams) {
        var teamz = self.mutableSetValueForKey("teams")
        teamz.addObject(team)
    }

    func getNumberOfTeams() -> Int {
        return self.teams.count;
    }

    func getTeams() -> [Teams] {
        var tmpsak: [Teams]
        tmpsak = self.teams.allObjects as [Teams]
        tmpsak = self.teams.allObjects as [Teams]

        return tmpsak
    }

}

which I thought was unrelated. However, renaming getTeams to getTeamsAsArray removed the problem. I am guessing that CoreData, when filling in the other end of the relationship, uses a built-in function called getTeams() (since the other class was called Teams). I accidentally overrode(?) it, causing it to fail.

Thank you for your suggestions, and I hope this can be helpful to someone else!

On a somewhat related note, a bug with similar symptoms was identified a few years ago (and appears to still be present), that shows itself in auto-generated code when using ordered many-to-many relationships.

这篇关于Swift和CoreData,关系问题(NSSet) - [NSSet intersectsSet:]:set参数不是一个NSSet的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆