使用Coredata Swift发送到实例的无法识别的选择器

Pra*_*nta 6 iphone core-data objective-c ios swift

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

import Foundation
import CoreData

@objc(Habit)
class Habit: NSManagedObject {

    @NSManaged var name: String
    @NSManaged var trackingType: NSNumber
}
Run Code Online (Sandbox Code Playgroud)

这是我的代码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

    }
Run Code Online (Sandbox Code Playgroud)

我一直收到错误"由于未捕获的异常终止应用程序'NSInvalidArgumentException',原因:' - [习惯setTrackingType:]:无法识别的选择器发送到实例0x7fdcbb002c90'"

在线self.habit?.trackingType = index

我在最近2天努力解决这个问题.

编辑:

模型习惯以下面的方式初始化

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

返回的列表在应用程序的任何位置都使用.基本上我从列表中获取和项目并更新其属性,然后再次保存

Rob*_*ers 6

好的,所以你得到错误的原因当然是因为引用的对象self.habit不是Habit对象.找出对象真正原因的最简单方法是调用:

print(NSStringFromClass(habit.class))
Run Code Online (Sandbox Code Playgroud)

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

作为旁注,您确实需要在从Core Data数据库中获取对象时检查错误.添加行:

if objects? == nil {
    print("An error occurred \error.localisedDescription")
}
Run Code Online (Sandbox Code Playgroud)

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

编辑:为了纠正Failed to call designated initializer on NSManagedObject class 'X'错误.如果未正确实例化,则会触发此错误NSManagedObject.你不能打电话,[[MyManagedObject alloc] init];你必须打电话initWithEntity:insertIntoManagedObjectContext:

MyManagedObject *obj = [[MyManagedObject alloc] initWithEntity:[NSEntityDescription entityForName:@"MyManagedObject" inManagedObjectContext:context] insertIntoManagedObjectContext:context];
Run Code Online (Sandbox Code Playgroud)

如果您不希望将对象obj插入上下文,则可以传递nil上下文参数.但是,如果您想要撤消管理以及将对象保存到数据库的能力,则需要将其与上下文相关联.

如果要对对象进行自定义初始化,则可以覆盖awakeFromInsertawakeFromFetch方法/函数.

  • 您要在任何地方调用“ self.habit = [[Habit alloc] init];”(或快速等效方法)吗?错误:“无法在NSManagedObject类上调用指定的初始化程序”通常意味着您在错误地初始化Habit对象。您无需调用alloc init即可:initWithEntity:insertIntoManagedObjectContext:。如果您不希望将“习惯”对象与上下文关联,则可以为“ NSManagedObjectContext”传递“ nil”。参见我的代码编辑。 (2认同)