Ios NSManagedObjectContext扩展中泛型函数中奇怪的Swift行为

Ios NSManagedObjectContext扩展中泛型函数中奇怪的Swift行为,ios,swift,generics,Ios,Swift,Generics,我目前正在Swift中进行一个iOS项目,我正在尝试使用Swift泛型和协议在NSManagedObjectContext之上构建某种扩展。我已经实现了一些方法,如以下方法: extension NSManagedObjectContext { func objectWhere<T: NSManagedObject>(entityClass: T.Type, predicate: NSPredicate) -> T? { let entityName =

我目前正在Swift中进行一个iOS项目,我正在尝试使用Swift泛型和协议在NSManagedObjectContext之上构建某种扩展。我已经实现了一些方法,如以下方法:

extension NSManagedObjectContext {

   func objectWhere<T: NSManagedObject>(entityClass: T.Type, predicate: NSPredicate) -> T? {
       let entityName = NSStringFromClass(entityClass)
       let request = NSFetchRequest(entityName: entityName)

       //...fetch object code here

       return result?.first
   }
}
接下来我要做的就是用这个协议扩展我的一个NSManagedObject子类。例如,在我当前的项目中,我有一个名为Person的类,它实现了这个协议。此协议应允许我在相同的NSManagedObjectContext扩展中创建upsert方法,如下所示:

func upsert<T where T: NSManagedObject, T: Updatable>(entityClass: T.Type, JSON: [NSObject: AnyObject]) -> T? {
    return nil
}
func objectWhere<T: NSManagedObject>(_: T.Type, predicate: NSPredicate) -> T? {
    let entityName = "\(T.self)"
    /* ... */
}
然而,最奇怪的是,这个问题的第一个方法工作得非常好。另外,当我从upsert函数中删除JSON:parameter时,它不会给出该错误,并且编译和运行完全正常


有人能告诉我发生了什么吗?

我认为类/结构或协议的类型不会返回它的隐式类型。但是,如果函数中只有一个参数,如
T.Type
,则会发生这种情况

下面是我的看法:

您可以使用postfixself表达式访问类型作为值。例如,SomeClass.self返回SomeClass本身,而不是SomeClass的实例。self返回SomeProtocol本身,而不是运行时符合SomeProtocol的类型的实例

这在将来可能会改变,我的手指也在祈祷。但现在,如果函数中有多个参数,则必须键入
self
postfix

protocol SomeProtocol {}

func someFunc1<T: SomeProtocol>(_: T.Type) -> String { "\(T.self)" }
func someFunc2<T: SomeProtocol>(_: T.Type, someInt: Int) -> String { "\(T.self) + \(someInt)"}

extension Int : SomeProtocol {}

someFunc1(Int) // returns "Swift.Int" <--- this is a bug
someFunc1(Int.self) // returns "Swift.Int"

someFunc2(Int, someInt: 42) // Expected memeber name or constructer call after type name
someFunc2(Int.self, someInt: 42) // returns "Swift.Int + 42"
协议SomeProtocol{}
func someFunc1(\:T.Type)->字符串{“\(T.self)”}
func someFunc2(类型:T.Type,someInt:Int)->字符串{“\(T.self)+\(someInt)”}
扩展名Int:SomeProtocol{}
someFunc1(Int)//返回“Swift.Int”T?{
让entityName=“\(T.self)”
/* ... */
}

更新:问题只是一个bug,请阅读:

我无法解释原因,但如果你写upsert(Person.self…我会编译。可能值得一个雷达。嗯,这确实是编译,奇怪的是,所有其他方法都没有.self。不过,我会检查我是否可以提交雷达。谢谢!
protocol SomeProtocol {}

func someFunc1<T: SomeProtocol>(_: T.Type) -> String { "\(T.self)" }
func someFunc2<T: SomeProtocol>(_: T.Type, someInt: Int) -> String { "\(T.self) + \(someInt)"}

extension Int : SomeProtocol {}

someFunc1(Int) // returns "Swift.Int" <--- this is a bug
someFunc1(Int.self) // returns "Swift.Int"

someFunc2(Int, someInt: 42) // Expected memeber name or constructer call after type name
someFunc2(Int.self, someInt: 42) // returns "Swift.Int + 42"
func objectWhere<T: NSManagedObject>(_: T.Type, predicate: NSPredicate) -> T? {
    let entityName = "\(T.self)"
    /* ... */
}