swift 3 - 将实体作为参数传递给函数

swift 3 - pass entity as argument to function

在swift的早期版本中,我有一个核心数据函数

func retrieveItemsForRelatedEntity(entity: String, relatedEntity: String, identifier: String, sortDescriptors: [NSSortDescriptor]?) -> Array<AnyObject>? {

    let appDel: AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
    let context: NSManagedObjectContext = appDel.managedObjectContext!
    let frequest = NSFetchRequest(entityName: entity)
    frequest.returnsObjectsAsFaults = false

    if sortDescriptors != nil {
        frequest.sortDescriptors = sortDescriptors
    } 

    switch relatedEntity {
    case "CostCentre":
        frequest.predicate = NSPredicate(format: "costCentre.identifier == '\(identifier)'")
        return try! context.executeFetchRequest(frequest)
    case "CostCentreDay":
        frequest.predicate = NSPredicate(format: "costCentreDay.identifier == '\(identifier)'")
        return try! context.executeFetchRequest(frequest)
    case "Resource":
        frequest.predicate = NSPredicate(format: "resource.identifier == '\(identifier)'")
        return try! context.executeFetchRequest(frequest)
    case "ResourceDay":
        frequest.predicate = NSPredicate(format: "resourceDay.identifier == '\(identifier)'")
        return try! context.executeFetchRequest(frequest)
    case "CostedDay":
        frequest.predicate = NSPredicate(format: "costedDay.identifier == '\(identifier)'")
        return try! context.executeFetchRequest(frequest)
    default:
        print("wrong entity for this function")
        return nil
    }
}

在 Swift 3.0 中,"Generic Result Type cannot be inferred",所以我可以不传入实体标题字符串,而是传入实体类型,然后为我的获取请求打开它吗?

试试这个:

let frequest = NSFetchRequest<NSFetchRequestResult>(entityName: entity)

回答你的问题

so instead of passing in the entity title Strings, can I pass in the entity Type, and switch on that for my fetch request?

是的,那将是最好的方法。像

 retrieveItemsForRelatedEntity(entity: NSManagedObject, relatedEntity: String, identifier: String, sortDescriptors: [NSSortDescriptor]?) -> Array<AnyObject>? {

You have to specify the generic type because otherwise the method call is ambiguous.

The first version is defined for NSManagedObject, the second version is generated automatically for every object using an extension, e.g:

此扩展名是自动生成的(如下所示 Animal 类型。

来自 Apple 关于从 Swift 2 更改为 Swift 3

的文档

NSFetchRequest is now a parameterized type based on a new NSFetchRequestResult protocol.

executeFetchRequest(...) 的函数名称也在 Swift 3

中更改
public func fetch<T : NSFetchRequestResult>(_ request: NSFetchRequest<T>) throws -> [T]

NSFetchRequest

的 Apple 文档更改示例

Swift 2

func findAnimals() {
    let request = NSFetchRequest(entityName:”Animal")
    do {
        guard let searchResults = try context.executeFetchRequest(request) as? [Animal] else {
            print("Results were not of the expected structure")
        }
        ... use(searchResults) ...
    } catch {
    print("Error ocurred during execution: \(error)")
}

}

Swift 3

func findAnimals() {
    let request: NSFetchRequest<Animal> = Animal.fetchRequest
    do {
        let searchResults = try context.fetch(request)
        ... use(searchResults) ...
    } catch {
        print("Error with request: \(error)")
    }
}

因此转换 Swift 2 中的代码以创建 NSFetchRequest

let frequest = NSFetchRequest(entityName: entity)

至Swift 3

let frequest: NSFetchRequest<YourEntityType> = YourEntityType.fetchRequest()

context.executeFetchRequest(frequest)

将会

context.fetch(frequest)

注意: 从网络上的其他示例来看,Animal.fetchRequest 的 Apple 文档代码示例可能是错误的,而应该是 Animal.fetchRequest()

请试试这个。它帮助了我。

func retrieveItemsForRelatedEntity(entity: String, relatedEntity: NSEntityDescription, identifier: String, sortDescriptors: [NSSortDescriptor]?) -> Array<AnyObject>? {

    let appDelegate = UIApplication.shared.delegate as! AppDelegate
    let context: NSManagedObjectContext = appDelegate.persistentContainer.viewContext

    let frequest = NSFetchRequest<NSFetchRequestResult>(entityName: entity) 

switch relatedEntity {
    case NSEntityDescription.entity(forEntityName: "CostCentre", in: context)!: