Swift和CoreData,关系问题(NSSet) – :设置参数不是NSSet

我一直在试图让我的头在使用CoreData和Swift添加关系中的对象。 我无所适从,我不明白为什么我的代码不起作用。 我正在尝试为“团队”添加一个“事件”。 我无法find接受的答案(这应该工作)和我的代码(不)之间的区别。

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 } } 

调用代码(从configuration视图):

 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() } } } 

错误信息:

 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 

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

YESSS! 我find了答案!

我已经在类Events.swift(关系的另一面)中创build了一个新的函数。

我写了下面的代码:

 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 } } 

我认为这是无关的。 但是,将getTeams重命名为getTeamsAsArray可以消除这个问题。 我猜测CoreData在填充关系的另一端时,使用了一个名为getTeams()的内置函数(因为其他类被称为Teams)。 我意外地超越(?)它,导致它失败。

感谢您的build议,我希望这可以帮助别人!

在某种程度上相关的说明中,几年前发现了一个类似症状的错误(并且似乎仍然存在),它使用有序的多对多关系在自动生成的代码中显示自己。

如果你使用目标C生成的NSManagedObject子类,它们包括用于添加单个对象的自定义方法 – 我认为这些都经过了尝试和testing,看起来比当前的快速。

理论上你只需要用你创build的任何新设置来设置新的设置。 一种select是:

  var matchobjs = matches.allObjects as [Event] matchobjs.append(event) matches = NSSet(array: matchobjs) 

然而,这个错误看起来非常类似于这个职位:

对我而言,哪一个看起来像是一些腥味会随着多对多的关系再次发生…