使用Coredata的Swift出现"unrecognized selector sent to instance"错误

7

每当我尝试更新核心数据模型的值时,都会收到此错误。这是我的模型:

import Foundation
import CoreData

@objc(Habit)
class Habit: NSManagedObject {

    @NSManaged var name: String
    @NSManaged var trackingType: NSNumber
}

这是我的tableViewCell代码。
override func setSelected(selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
        if selected {
            self.accessoryType = UITableViewCellAccessoryType.Checkmark
            if self.habit? != nil {
                self.habit?.trackingType = index

            }

        } else {
            self.accessoryType = UITableViewCellAccessoryType.None
        }
        // Configure the view for the selected state

    }

我一直遇到错误"Terminating app due to uncaught exception 'NSInvalidArgumentException',原因:'-[Habit setTrackingType:]: unrecognized selector sent to instance 0x7fdcbb002c90'"

在这行代码上: self.habit?.trackingType = index

我为此挣扎了两天,仍然无法解决。

编辑:

habit模型是以下方式初始化的:

func getHabits() -> [AnyObject]{
        let entityDescription =
        NSEntityDescription.entityForName("Habit",
            inManagedObjectContext: managedObjectContext!)

        let request = NSFetchRequest()
        request.entity = entityDescription
//        
//        let pred = NSPredicate(format: "(trackingType != -1)")
//        request.predicate = pred

        var error: NSError?

        var objects = managedObjectContext?.executeFetchRequest(request,
            error: &error)

        return objects!;
    }

返回的列表在应用程序中被广泛使用。基本上,我从列表中获取一个项目,更新其属性,然后再次保存它。

我已经查看了所有这些链接,但是它们都没有帮助。我已经编辑了我的问题,请您发表评论。 - Praneeth Chinta
我认为这与内存有关,但我无法在Swift中找到答案。 - Praneeth Chinta
你是自动生成这个类的吗? - Wain
没有定义索引。是的,我已经使用Xcode从模型生成了类。 - Praneeth Chinta
如果使用Swift 3,XCode Beta 8,则以下是另一个Go的答案- https://forums.developer.apple.com/thread/50885 - Gugulethu
显示剩余3条评论
1个回答

15

好的,你得到错误的原因几乎肯定是因为self.habit所引用的对象不是Habit对象。查找对象真正的内容最简单的方法是调用:

print(NSStringFromClass(habit.class))

当使用核心数据和自定义NSManagedObjects时,你需要确保实体:“Habit”(在你的数据模型中)的类设置为Habit。这可以确保Core Data将带有实体描述“Habit”的获取对象强制转换为Habit类。如果没有这样做,getHabits函数将返回一个NSManagedObject数组而不是Habit数组。如果是这种情况,那么代码:println(NSStringFromClass(habit.class))将在调试器中打印出"NSManagedObject"。

另外,你真的需要在从Core Data数据库获取对象时检查错误。添加以下行:

if objects? == nil {
    print("An error occurred \error.localisedDescription")
}

如果有任何错误,请原谅我的迅速,我通常使用Objective-C。

编辑:为了纠正未能调用NSManagedObject类“X”的指定初始化程序错误。当您没有正确实例化NSManagedObject时,会触发此错误。您不应该调用 [[MyManagedObject alloc] init];,而是必须调用 initWithEntity:insertIntoManagedObjectContext

MyManagedObject *obj = [[MyManagedObject alloc] initWithEntity:[NSEntityDescription entityForName:@"MyManagedObject" inManagedObjectContext:context] insertIntoManagedObjectContext:context];
如果您不想将对象obj插入上下文中,可以通过传递一个nil上下文参数来实现。但是,如果您想要撤消管理和将对象保存到数据库的能力,则需要将其与上下文关联。
如果您想自定义对象的初始化,则可以覆盖awakeFromInsertawakeFromFetch方法/函数。

我将代码更改如下 'code' if self.habit? != nil { NSLog(NSStringFromClass(self.habit?.classForCoder)) self.habit?.trackingType = index } 'code' 并且它正确地打印了类名 Habit。CoreData: error: Failed to call designated initializer on NSManagedObject class 'Habit' Habit -[Habit setTrackingType:]: unrecognized selector sent to instance 0x7fe452299010 *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Habit setTrackingType:]: unrecognized selector sent to instance' - Praneeth Chinta
2
你是否在任何地方调用了 self.habit = [[Habit alloc] init];(或者 Swift 的等效语句)?错误信息:“Failed to call designated initializer on NSManagedObject class”通常意味着你错误地初始化了 Habit 对象。你需要调用 initWithEntity:insertIntoManagedObjectContext: 而不是 alloc init。如果你不想将 Habit 对象与上下文关联,可以将 NSManagedObjectContext 设置为 nil。请参考我的代码编辑。 - Rob Sanders

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接