gpt4 book ai didi

ios - NSManagedObjectContext 扩展中的通用函数中的奇怪 Swift 行为

转载 作者:行者123 更新时间:2023-11-30 14:14:42 25 4
gpt4 key购买 nike

我目前正在 Swift 中开发一个 iOS 项目,我正在尝试使用 Swift 泛型和协议(protocol)在 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
}
}

这个方法工作得很好,但是当我想实现更新插入时,就会出现棘手的情况。基本上我正在做的是创建一个像这样的协议(protocol):

protocol Updatable {
static func primaryKeyJSON() -> String

static func primaryKey() -> String

func populate(JSON: [NSObject: AnyObject], context: NSManagedObjectContext)

func update(JSON: [NSObject: AnyObject], context: NSManagedObjectContext)
}

我要做的下一件事是使用此协议(protocol)扩展我的 NSManagedObject 子类之一。例如,在我当前的项目中,我有一个名为 Person 的类,它实现了此协议(protocol)。这个协议(protocol)应该允许我在同一个 NSManagedObjectContext 扩展中创建一个 upsert 方法,如下所示:

func upsert<T where T: NSManagedObject, T: Updatable>(entityClass: T.Type, JSON: [NSObject: AnyObject]) -> T? {
return nil
}

问题是,每当我调用此方法时,Xcode 都会给出错误:“类型名称后预期的成员名称或构造函数调用”。

c.upsert(Person, JSON: ["test": "sometest"])
然而,最奇怪的是这个问题的第一种方法工作得很好。另外,当我从 upsert 函数中删除 JSON: 参数时,它不会给出该错误,并且编译和运行完全正常。

谁能告诉我发生了什么事吗?

最佳答案

我不认为类/结构或协议(protocol)的类型会隐式返回其类型。然而,当您的函数中只有一个参数(例如 T.Type)时,就会发生这种情况。

这就是 Apples Swift Library说:

You can use the postfix self expression to access a type as a value. For example, SomeClass.self returns SomeClass itself, not an instance of SomeClass. And SomeProtocol.self returns SomeProtocol itself, not an instance of a type that conforms to SomeProtocol at runtime.

这将来可能会改变,我也祈祷。但现在,当函数中有多个参数时,您必须输入 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)"
/* ... */
}

更新:该问题只是一个错误,请阅读 here :

关于ios - NSManagedObjectContext 扩展中的通用函数中的奇怪 Swift 行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31337598/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com