使用 Coredata Swift 发送到实例的无法识别的选择器 [英] unrecognized selector sent to instance with Coredata Swift

查看:10
本文介绍了使用 Coredata Swift 发送到实例的无法识别的选择器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I keep getting this error whenever I try to update a value of core data model. Here is my model

import Foundation
import CoreData

@objc(Habit)
class Habit: NSManagedObject {

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

这是我的代码 tableViewCell

Here is my code 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

    }

我不断收到错误由于未捕获的异常‘NSInvalidArgumentException’而终止应用程序,原因:‘-[Habit setTrackingType:]:无法识别的选择器发送到实例 0x7fdcbb002c90’"

在线self.habit?.trackingType = index

at line self.habit?.trackingType = index

过去 2 天我都在努力解决这个问题.

I am struggling to fix this for last 2 days.

模型习惯的初始化方式如下

The model habit is initialized in below way

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

返回的列表在应用中随处可见.基本上我从列表中获取和项目并更新其属性,然后再次保存它

The returned list is used everywhere in the app. Basically I fetch and item from the list and update its attributes and then save it again

推荐答案

好吧,你得到错误的原因肯定是因为 self.habit 引用的对象不是 习惯对象.找出对象到底是什么的最简单方法是调用:

Ok so the reason you are getting the error is most certainly because the object referenced by self.habit is not a Habit object. The easiest way to find out what the object really is is to call:

print(NSStringFromClass(habit.class))

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

With core data and custom NSManagedObjects you need to make sure that the entity: 'Habit' (in your data model) has a class set to Habit. This makes sure that Core Data casts your fetched objects with an entity description of 'Habit' to the Habit class. If you are not doing this then the getHabits func will be returning an array of NSManagedObjects not an array of Habits.If this is the case then the code: println(NSStringFromClass(habit.class)) will print "NSManagedObject" to the debugger.

顺便提一下,当您从 Core Data 数据库中获取对象时,您确实需要检查错误.添加行:

As a side note, you really need to check for errors when you fetch objects from a Core Data database. Add the lines:

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

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

Please forgive my swift if there are any errors, I normally use Objective-C.

为了更正 Failed to call specified initializer on NSManagedObject class 'X' 错误.当您没有正确实例化 NSManagedObject 时会触发此错误.你不能调用 [[MyManagedObject alloc] init]; 你必须调用 initWithEntity:insertIntoManagedObjectContext 代替:

In order to correct Failed to call designated initializer on NSManagedObject class 'X' error. This error is fired when you do not correctly instantiate an NSManagedObject. You must not call [[MyManagedObject alloc] init]; you have to call initWithEntity:insertIntoManagedObjectContext instead:

MyManagedObject *obj = [[MyManagedObject alloc] initWithEntity:[NSEntityDescription entityForName:@"MyManagedObject" inManagedObjectContext:context] insertIntoManagedObjectContext:context];

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

If you do not want the object obj to be inserted into a context you can pass through a nil context argument. However, if you want undo management and the ability to save the object to the database it needs to be associated with a context.

如果你想自定义一个对象的初始化,那么你可以覆盖 awakeFromInsertawakeFromFetch 方法/函数.

If you want to have a custom initialisation of an object then you can override the awakeFromInsert and awakeFromFetch methods/functions.

这篇关于使用 Coredata Swift 发送到实例的无法识别的选择器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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