快速将通用类作为参数传递给函数

时间:2018-07-04 12:55:47

标签: ios swift generics core-data nsmanagedobject

下面是我的方法,其中对托管对象的类约会进行提取。我需要对其他类似的托管对象类使用相同的功能。如何在每次需要时传递不同的“类”作为参数。并使用它来获取我当前拥有的“约会”类。我可能需要使用泛型。不知道如何。

func getAppointmentArray(aPredicate : String , aModel : Any) -> [Any]
{
    var apptArr = [Any]()
    let fetchRequest = NSFetchRequest<Appointment>(entityName: "Appointment")
    fetchRequest.returnsObjectsAsFaults = false
    fetchRequest.predicate = NSPredicate(format: aPredicate)
    do{
        let records = try managedObjectContext.fetch(fetchRequest)

        if let records = records as? [NSManagedObject]{
            if !records.isEmpty{

                print("coreData apptmnt result : \(records)")
                var appointment : Appointment?

                for obj in records
                {

                }
            }else{
                print("No records found")
                apptArr = []
            }
        }
    }catch{
        print("Error")
         apptArr = []
    }
   return apptArr
}

2 个答案:

答案 0 :(得分:2)

对于泛型,您可以执行以下操作:

class FetchingDataHandler<T>{
func getAppointmentArray<T>(forClass : T, aPredicate : String , aModel : Any) -> [Any]
  {
  }
}

答案 1 :(得分:2)

Objc.io的好人为此提供了一个非常好的方法。首先声明一个继承如下“ NSFetchRequestResult ”协议的协议。

protocol Managed: class, NSFetchRequestResult {
    static var entityName: String { get }
} 

现在,我们可以为我们的协议受管理的”提供一个非常方便的协议扩展。 我们执行“ 自我:NSManagedObject ”检查,因为我们希望NSManagedObject类的静态方法entity()获得描述的“ NSEntityDescription ”。与我们班级相关的实体。 特别是通过这种方式,我们为符合协议的所有ManagedObject动态(方便地)获取实体名称。

extension Managed where Self: NSManagedObject {
    static var entityName: String { return entity().name! }
}

我们现在通过提供一种方法来改进协议扩展,该方法可以方便地创建获取请求,然后调用配置块,无论谁调用它,该配置块均可用于配置创建的获取请求。在此方法的最后,我们使用创建的请求进行提取。

extension Managed where Self: NSManagedObject {
        static var entityName: String { return entity().name! }

        //Continued
        static func fetch(in context: NSManagedObjectContext, configurationBlock: (NSFetchRequest<Self>) -> ()) -> [Self] {
            let request = NSFetchRequest<Self>(entityName: Self.entityName)
            configurationBlock(request)
            return try! context.fetch(request)
        }
}

如您所见,我们在这里做以下事情:

  • 我们充分利用协议和协议扩展来简化生活。
  • 我们获得实体名称,而无需为可能创建的每个具体管理对象类编写方法。这对于符合“ Managed”的每个托管对象类都是可重用的
  • 我们编写的获取方法利用了动态便捷的 entityName
  • fetch方法再次使用 Self ,它在此处与实现无关。这样,我们就可以制作本身是通用的FetchRequests。
  • 我们提供了一种方便的方法来将请求配置为调用此方法的人。
  • 最后,我们在提取后返回结果,该结果也是动态的 [Self]

要查看我们的协议在起作用,我们可以针对您的情况进行操作:

class Appointment: NSManagedObject, Managed{
    //properties for attributes
    //etc...
    //Will I get free implementation for entity name and a fetch method
    //without writing extra code ?
    //Yes why not
}

测试我们的来之不易的知识:

let aPredicate = "......
let context: NSManagedObjectContext.....
let appointments = Appointment.fetch(in: context) { fetchRequest in
    //Configuration code like adding predicates and sort descriptors
    fetchRequest.predicate = NSPredicate(format: aPredicate)
}

如果其他ManagedObject符合协议,则可以使用相同的模式。例如,符合我们的 Managed 协议的Doctor ManagedObject子类:

let aPredicate = "......
let context: NSManagedObjectContext.....
let doctors = Doctor.fetch(in: context) { fetchRequest in
    //Configuration code like adding predicates and sort descriptors
    fetchRequest.predicate = NSPredicate(format: aPredicate)
}