如何在Swift

时间:2015-06-27 17:47:24

标签: ios xcode swift generics casting

我即将学习斯威夫特。我想写一个类,为我处理Cora Data任务。在这种情况下,应该可以将实体名称和元组数组传递给函数,然后函数将元组解释为NSPredicates的键值对,以检索与它们匹配的ManagedObjects。由于NSPredicate需要具有特定类型的值,我也尝试传递值的类型。但我无法绕过那个"''不是一种类型"编译错误(最后一行代码)。如何将值转换为传递的类型?或者你会以完全不同的方式创建NSPredicate吗?

class func getManagedObjectsWithEntityName<T>(entityName: String, keysAndValues: [(key: String, value: AnyObject, type: T.Type)]) -> [NSManagedObject] {

    let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
    let managedContext = appDelegate.managedObjectContext

    let fetchRequest = NSFetchRequest(entityName: entityName)
    var predicates: [NSPredicate] = []

    for tuple in keysAndValues {
        let t = tuple.type
        predicates.append( NSPredicate(format: tuple.key + " = %@", tuple.value as t)!)
    }

    ...
}

1 个答案:

答案 0 :(得分:1)

这里不需要使用泛型,你似乎不需要访问任何你将用作泛型的类的成员/函数。

您所拥有的是一个选择:您可以将值视为符合CVarArgType,允许您将它们直接插入NSPredicate构造函数,或者您可以将值作为字符串并通过构建字符串表达式来构造谓词。以下是使用CVarArgType的示例:

func getManagedObjectsWithEntityName(entityName: String, keysAndValues: 
    [(key: String, value: CVarArgType)]) -> [NSManagedObject] {

    ...

    let fetchRequest = NSFetchRequest(entityName: entityName)
    var predicates: [NSPredicate] = []

    for tuple in keysAndValues {
        predicates.append( NSPredicate(format: "%K = %@", tuple.key, tuple.value))
    }

    ...

}

你的泛型不工作的原因是你设置了占位符,但是函数sig中的tuple.type实际上是T.Type(而不仅仅是T)。如果您将元组规范更改为(key: String, value: AnyObject, type: T),那么您将能够投射let t = tuple.type as! T。但是你会遇到问题,因为NSPredicate没有采用类型T - 从而解决方案不是真的使用泛型,而是使用类似上面的东西。同样值得注意的是,避免使用.type和.value这样的变量名称是个好主意,因为在某些情况下这些会导致混淆,特别是对于NSManagedObjects(具有.value)。至少值得知道这可能是问题的原因......