CoreData - 相当于使用带有示例的类别 - Swift

Posted

技术标签:

【中文标题】CoreData - 相当于使用带有示例的类别 - Swift【英文标题】:CoreData - Equivalent of Using Categories w/ Example - Swift 【发布时间】:2014-08-03 17:07:56 【问题描述】:

我想知道如何在下面为我的 CoreData NSManagedObject 客户端创建相当于类别的内容:

我知道扩展现在是 Swift 中类别的替代品 - 但是我不确定它们的实现。这是我在下面扣除的:

class Client: NSManagedObject 

    @NSManaged var name: String
    @NSManaged var projects: NSSet



extension Client 

    func addClientWithName(name:NSString, context:NSManagedObjectContext) -> Client 
        var client:Client = Client();

        // Check for name in the database already exists
        let request:NSFetchRequest = NSFetchRequest(entityName: "Client")
        let sortDescriptor:NSSortDescriptor = NSSortDescriptor(key: "name", ascending: true)
        let sortDescriptorsAry:NSArray = [sortDescriptor]
        request.sortDescriptors = sortDescriptorsAry
        request.predicate = NSPredicate(format: "name = %@", name)

        var error:NSError?
        let matches:NSArray = context.executeFetchRequest(request, error: &error)

        if matches.count == 0 

            //Add new Client
            var newClient:NSEntityDescription = NSEntityDescription.insertNewObjectForEntityForName("Client", inManagedObjectContext: context) as NSEntityDescription
            newClient.setValue(name, forKey: "name")

            context.save(nil);

         else 
            client = matches.lastObject as Client
        

        return client
    

然而,有了这个实现,这是我到目前为止得到的错误:

CoreData: error: Failed to call designated initializer on NSManagedObject class "Ttc9AppName6Client"

关于可能导致此问题的任何想法?

编辑: 这就是我从其他类中调用该方法的方式:

@IBAction func saveBtnTapped(UIButton) 
    println("save btn tapped")
    var client:Client = Client().addClientWithName("Woofy Face", context: self.managedObjectContext)

【问题讨论】:

您是否在核心数据模型检查器中为实体类名称添加了模块名称的前缀?比较***.com/a/25076929/1187415。 @MartinR - 我已经仔细检查过 - 它的前缀肯定是“AppName.Client” 【参考方案1】:

我认为您的问题与类别/扩展无关。

 var client:Client = Client();

调用NSManagedObject的指定初始化器,这个对象 如果 fetch 请求没有找到匹配的对象,则返回。

在这种情况下,您可能想要返回新创建的对象。

还要注意

insertNewObjectForEntityForName:inManagedObjectContext:

返回一个托管对象,而不是实体描述。

另外,

var client:Client = Client().addClientWithName(...)

还创建一个客户端对象而不使用指定的初始值设定项。 您应该将方法定义为 类方法

所以你的代码应该是这样的:

 class func addClientWithName(name:NSString, context:NSManagedObjectContext) -> Client 
    var client:Client

    let request:NSFetchRequest = NSFetchRequest(entityName: "Client")
    let sortDescriptor:NSSortDescriptor = NSSortDescriptor(key: "name", ascending: true)
    let sortDescriptorsAry:NSArray = [sortDescriptor]
    request.sortDescriptors = sortDescriptorsAry
    request.predicate = NSPredicate(format: "name = %@", name)

    var error:NSError?
    let matches:NSArray = context.executeFetchRequest(request, error: &error)

    if matches.count == 0 
        //Add new Client
        client = NSEntityDescription.insertNewObjectForEntityForName("Client", inManagedObjectContext: context) as Client
        client.name = name
        context.save(nil)
     else 
        client = matches.lastObject as Client
    
    return client

它会被称为

let client:Client = Client.addClientWithName("Woofy Face", context: self.managedObjectContext)

【讨论】:

谢谢:我知道你从哪里来,并且已经实现了你的解决方案,但我仍然得到:CoreData:错误:无法在 NSManagedObject 类“_TtC9AppName6Client”上调用指定的初始化程序 注意你的函数应该是一个类函数class func addClientWithName ...并且应该被称为let cl1 = Client.addClientWithName(...)。 - 我现在测试了该代码,它似乎可以工作。 我刚刚投入到 IBAction 中,它在那里工作正常,只是似乎不在扩展中 这是一个很好的解决方案,但我无法实现它,因为我通过协议移动对象。嵌入类函数并不能消除错误。有什么想法吗? @Japes:对不起,我不明白你在问什么。

以上是关于CoreData - 相当于使用带有示例的类别 - Swift的主要内容,如果未能解决你的问题,请参考以下文章

CoreData 性能重复实体与属性

带有 CoreData 的 TextField

iPhone SDK:带有核心数据表示例代码的 SearchDisplayController?

CoreData - 原始访问器作为属性?

CoreData:按类别集中的索引对项目进行排序

如何使用 Firebase 发送带有类别的通知 [重复]