快速将通用类作为参数传递给函数 [英] Passing generic Class as argument to function in swift

查看:114
本文介绍了快速将通用类作为参数传递给函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Below is my method in which there is fetch I make on a Managed object Class Appointment. I need to use same function for other similar managed object Classes. How do I pass different "Class" as parameter every time as I need. And also use it to fetch as I have currently "Appointment" Class. I might need to use Generics may be. Dont know how though.

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
}


推荐答案

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

The good folks at Objc.io provide a really good approach for this. First declare a protocol which inherits 'NSFetchRequestResult' protocol as below.

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

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

Now we can provide a very convenient protocol extension for our protocol 'Managed'. We do the check 'Self: NSManagedObject' as we want the static method entity() of the NSManagedObject class to get the 'NSEntityDescription' describing the entity associated with our class. Particularly this way we get the entity name dynamically(and conveniently too) for all our ManagedObjects that conform to our protocol.

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

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

We now improve the protocol extension by providing a method which conveniently creates a fetch request and then calls a configuration block which might be used to configure the created fetch request by whoever calls it. At the end of this method we do a fetch using the created request.

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。

  • 我们提供了一种方便的方法来将请求配置为调用此方法的人。

  • 然后在atlast我们在获取后返回的结果也是动态的 [Self]

  • We make good use of protocols and protocol extensions for making our life easy.
  • We get the entity name without needing to write a method for each concrete managed object class that we might create. This is reusable for every managed object class that will conform to 'Managed'
  • The fetch method that we wrote makes use of the dynamic and convenient entityName.
  • The fetch method again makes use of Self which is implementation independent here. This way we make FetchRequests which are generic in itself.
  • We provide a convenient way to configure the request to whoever calls this method.
  • And at atlast we return result after fetching which is also dynamic [Self]

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

To see our protocol in action we can do this for your case:

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
}

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

Testing our hard earned knowledge:

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符合协议,则可以使用相同的模式。例如,符合以下条件的Doctor ManagedObject子类我们的托管协议:

You can use the same pattern for any other ManagedObjects if they conform to the protocol. Eg a Doctor ManagedObject subclass conforming to our Managed protocol:

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)
}

这篇关于快速将通用类作为参数传递给函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆