ios - findOrCreate 在 Swift 3 中没有硬编码 entityName

标签 ios swift core-data swift3 xcode8

Xcode 8 在您的 NSManagedObject 子类上提供了一个自动生成的 extension,看起来像这样:

//  Animal+CoreDataProperties.swift

import Foundation
import CoreData

extension Animal {

  @nonobjc public class func fetchRequest() -> NSFetchRequest<Animal> {
    return NSFetchRequest<Animal>(entityName: "Animal");
  }

  // etc...
}

这很棒,因为我们不再需要硬编码字符串来创建 NSFetchRequest 对象。但是,Apple 尚未提供引用此方法的协议(protocol),也未提供引用 entityName 本身的协议(protocol)。

例如,如果我想创建这样的方法:

protocol ManagedObjectType: class {}

extension ManagedObjectType where Self: NSManagedObject {

  static func findOrCreate(inContext context: NSManagedObjectContext, matchingPredicate predicate: NSPredicate) -> Self {
    // etc...
  }
}

...我无法利用任何 NSManagedObject 子类的 fetchRequest 方法(因为它定义在子类),所以我不得不自己再次对这些字符串进行硬编码(即使 Xcode 已经这样做了)。

知道解决这个问题的方法吗?我在想这些事情:

protocol ManagedObjectType: class {
  static func fetchRequest() -> NSFetchRequest<NSFetchRequestResult>
}

extension Animal: ManagedObjectType {}

但这不起作用,因为协议(protocol)不支持 where 子句,所以我不能指定 Self 是一个 NSFetchRequestResult ,这意味着当我开始使用它时,像这样:

let request: NSFetchRequest<Self> = self.fetchRequest()

... Xcode 给我这个错误:

'fetchRequest' produces 'NSFetchRequest<NSFetchRequestResult>', not the expected contextual result type 'NSFetchRequest<Self>'

有人解决过这个问题吗?

最佳答案

您可以为此目的使用模板。所以你的代码看起来像这样:

static func findOrCreate<T: NSManagedObject>(inContext context: NSManagedObjectContext, matchingPredicate predicate: NSPredicate) -> T {
    // etc...
}

关于ios - findOrCreate 在 Swift 3 中没有硬编码 entityName,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40630912/

相关文章:

ios - 为什么不透明样式在 SearchBar 上不起作用?

ios - 在 Xcode 6 中手动创建空应用程序后的全屏问题

swift - 不兼容对象的 NSCoding (MKMapItem)

ios - 与 Core Data 和 RestKit 无关的关系

ios - 可以使用核心数据在 iOS/核心图形中撤消/重做吗?

ios - 将iOS/Mac应用程序与dame数据模型同步?

objective-c - 使用他们的 iOS Hook 将照片发布到 Instagram

ios - Cloudkit 数据库在启动到 App Store 之前被清除了吗?

swift - 有没有办法获取变量中advertisementData的值

Swift 变量语法