代码之家  ›  专栏  ›  技术社区  ›  Magoo

一般获取请求

  •  2
  • Magoo  · 技术社区  · 7 年前

    我有一个静态函数 NSManagedObject

    NSManagedObject.get(type: MYUser.self, with: ("id", "SomeUserId"), in: context)

    extension NSManagedObject {
    
        static func get<M: NSManagedObject>(type: M.Type, with kvp: (String, CVarArg), in context: NSManagedObjectContext) -> M? {
    
         guard let name = entity().name else { return nil }
         guard M.entity().propertiesByName[kvp.0] != nil else { Assert("\(name) does not have \(kvp.0)"); return nil }
    
         let fetchRequest = NSFetchRequest<M>(entityName: name)
         fetchRequest.predicate = NSPredicate(format: "\(kvp.0) == %@", kvp.1)
    
         do {
                let object = try context.fetch(fetchRequest)
                if let foundObject = object.first { return foundObject }
                return nil
            } catch {
                return nil
            }
        }
    }    
    

    我想要的语法是

    MYUser.get(with: ("id", "SomeUserId"), in: context)

    NSFetchRequest<M>(entityName: name)

    NSFetchRequest<???>(entityName: name)

    提前谢谢

    2 回复  |  直到 7 年前
        1
  •  2
  •   Sweeper    7 年前

    如果你不介意的话 MYUser 两次,你可以移除 type 参数并指定类型,以便Swift可以推断 M :

    extension NSManagedObject {
    
        static func get<M: NSManagedObject>(with kvp: (String, CVarArg), in context: NSManagedObjectContext) -> M? {
    
            guard let name = entity().name else { return nil }
            guard M.entity().propertiesByName[kvp.0] != nil else {
                print("\(name) does not have \(kvp.0)")
                return nil
            }
    
            let fetchRequest = NSFetchRequest<M>(entityName: name)
            fetchRequest.predicate = NSPredicate(format: "\(kvp.0) == %@", kvp.1)
    
            do {
                let object = try context.fetch(fetchRequest)
                if let foundObject = object.first { return foundObject }
                return nil
            } catch {
                return nil
            }
        }
    }
    
    // usage:
    let user: MYUser? = MYUser.get(with: ("id", "SomeUserId"), in: context)
    

    我的用户 两次,我想不出任何解决办法。如果 NSManagedObject 如果是协议,你可以用 Self 在那里。

        2
  •  1
  •   Magoo    7 年前

    基于链接 Passing generic Class as argument to function in swift Martin R

    protocol Managed where Self: NSManagedObject { }
    
    extension Managed where Self: NSManagedObject {
    
    static func get(with kvp: (String, CVarArg), in context: NSManagedObjectContext) -> Self? {
    
        guard let name = entity().name else { return nil }
        guard entity().propertiesByName[kvp.0] != nil else { Assert("\(name) does not have \(kvp.0)"); return nil }
    
        let fetchRequest = NSFetchRequest<Self>(entityName: name)
        fetchRequest.predicate = NSPredicate(format: "\(kvp.0) == %@", kvp.1)
    
        do {
            let object = try context.fetch(fetchRequest)
            if let foundObject = object.first { return foundObject }
            return nil
        } catch {
            return nil
        }
    }