Generics 带泛型的Swift-Fetch方法

Generics 带泛型的Swift-Fetch方法,generics,core-data,swift,Generics,Core Data,Swift,其思想是使用Coredata获取“类型化”数据 已更新 class func retrieve<T: AnyObject>(entityName:T.Type, sortBy:String? = nil, isAscending:Bool? = true, predicate:NSPredicate? = nil) -> AnyObject[] { println("\(entityName)") let request = NSFetchRequest

其思想是使用Coredata获取“类型化”数据

已更新

class func retrieve<T: AnyObject>(entityName:T.Type, sortBy:String? = nil, isAscending:Bool? = true, predicate:NSPredicate? = nil) -> AnyObject[]    {

    println("\(entityName)")
    let request = NSFetchRequest(entityName: "Users")
    request.returnsObjectsAsFaults = false
    if predicate != nil {
        request.predicate = predicate
    }

    if (sortBy != nil){
        var sorter: NSSortDescriptor = NSSortDescriptor(key: sortBy , ascending: isAscending!)
        request.sortDescriptors = [sorter]
    }


    var error: NSError? = nil
    var fetchedResult = myDataModel.managedObjectContext.executeFetchRequest(request, error: &error)
    if !error {
        println("errore: \(error)")
    }


    println("retrieved \(fetchedResult.count) elements for \(entityName)")
    return fetchedResult

}
在哪里


您有什么建议吗?

您可以使用
NSStringFromClass
,只要您使用
@objc(ModelClassName)

另一个对您来说更重要的选项可能是:

protocol EntityWithName {
    class func entityName() -> String
}

extension MyModelObject : EntityWithName {
    class func entityName() -> String {
        return "MyModelObject"
    }
}

extension NSManagedObjectContext {

    // Create an instance of T and insert it into the Context (this is normal)
    func insert<T:NSManagedObject where T:EntityWithName>(entityClass:T.Type) -> T? {
        let entityDescription = NSEntityDescription.entityForName(entityClass.entityName(), inManagedObjectContext: self)

        if !entityDescription {
            return nil
        }

        return NSManagedObject(entity: entityDescription, insertIntoManagedObjectContext: self) as? T
    }
}

let myModelObject = myContext.insert(MyModelObject.Self)

对于每个用户可修改的类文件(而不是uu1),这应该没问题,因为mogenerator生成entityName类方法。

您可以使用
NSStringFromClass
,只要使用
@objc(ModelClassName)

另一个对您来说更重要的选项可能是:

protocol EntityWithName {
    class func entityName() -> String
}

extension MyModelObject : EntityWithName {
    class func entityName() -> String {
        return "MyModelObject"
    }
}

extension NSManagedObjectContext {

    // Create an instance of T and insert it into the Context (this is normal)
    func insert<T:NSManagedObject where T:EntityWithName>(entityClass:T.Type) -> T? {
        let entityDescription = NSEntityDescription.entityForName(entityClass.entityName(), inManagedObjectContext: self)

        if !entityDescription {
            return nil
        }

        return NSManagedObject(entity: entityDescription, insertIntoManagedObjectContext: self) as? T
    }
}

let myModelObject = myContext.insert(MyModelObject.Self)

对于每个用户可修改的类文件(而不是uu1),应该没有问题,因为mogenerator生成entityName类方法。

如果如@David所指出的,将
@objc(ModelClassName)
添加到模型类中,下面是一个简化版本:

func retrieve<T: NSManagedObject>(entityClass:T.Type, sortBy:String? = nil, isAscending:Bool = true, predicate:NSPredicate? = nil) -> T[] {
    let entityName = NSStringFromClass(entityClass)
    let request    = NSFetchRequest(entityName: entityName)

    request.returnsObjectsAsFaults = false
    request.predicate = predicate

    if (sortBy != nil) {
        var sorter = NSSortDescriptor(key:sortBy , ascending:isAscending)
        request.sortDescriptors = [sorter]
    }

    var error: NSError? = nil
    var fetchedResult = myDataModel.managedObjectContext.executeFetchRequest(request, error: &error)
    if !error {
        println("errore: \(error)")
    }

    println("retrieved \(fetchedResult.count) elements for \(entityName)")
    return fetchedResult
}

如@David所指出的,如果将
@objc(ModelClassName)
添加到模型类中,那么下面是一个简化版本:

func retrieve<T: NSManagedObject>(entityClass:T.Type, sortBy:String? = nil, isAscending:Bool = true, predicate:NSPredicate? = nil) -> T[] {
    let entityName = NSStringFromClass(entityClass)
    let request    = NSFetchRequest(entityName: entityName)

    request.returnsObjectsAsFaults = false
    request.predicate = predicate

    if (sortBy != nil) {
        var sorter = NSSortDescriptor(key:sortBy , ascending:isAscending)
        request.sortDescriptors = [sorter]
    }

    var error: NSError? = nil
    var fetchedResult = myDataModel.managedObjectContext.executeFetchRequest(request, error: &error)
    if !error {
        println("errore: \(error)")
    }

    println("retrieved \(fetchedResult.count) elements for \(entityName)")
    return fetchedResult
}

我似乎无法让
@objc
注释为我工作,因此我使用了:

let fetchRequest = NSFetchRequest(entityName: NSStringFromClass(entityClass).componentsSeparatedByString(".").last!)

这可以深入到实体名称。

我似乎无法让
@objc
注释对我起作用,因此我使用了:

let fetchRequest = NSFetchRequest(entityName: NSStringFromClass(entityClass).componentsSeparatedByString(".").last!)

这可以深入到实体名称。

如果我能向David征求您的意见,我不会使用绑定到objective-c。我认为关于“然而,由于您的模型对象需要将NSManagedObject作为一个超类,因此试图避免“绑定到objective-c”实际上是毫无意义的”,所以一个好的解决方案是Jean an您向我提出的:使用注释@objc(Users)和NSStringFromClass。更清楚。我喜欢这个而不是分机。您关于插入的解决方案与我根据您之前的建议采用的相同(没有EntityWithName)。如果我征求大卫的意见,我不会使用objective-c的绑定。我认为关于“然而,由于您的模型对象需要将NSManagedObject作为一个超类,因此试图避免“绑定到objective-c”实际上是毫无意义的”,所以一个好的解决方案是Jean an您向我提出的:使用注释@objc(Users)和NSStringFromClass。更清楚。我喜欢这个而不是分机。您关于插入的解决方案与我根据您之前的建议采用的相同(没有EntityWithName)。谢谢
@objc(Client)
class Client : NSManagedObject {
    ...    
}

retrieve(Client)  // This would get all clients in the database.
let fetchRequest = NSFetchRequest(entityName: NSStringFromClass(entityClass).componentsSeparatedByString(".").last!)