通用 FetchRequest
Generic FetchRequest
我有一个扩展 NSManagedObject
的静态函数来获取这样的对象...
NSManagedObject.get(type: MYUser.self, with: ("id", "SomeUserId"), in: context)
extension NSManagedObject {
static func get<M: NSManagedObject>(type: M.Type, with kvp: (String, CVarArg), in context: NSManagedObjectContext) -> M? {
guard let name = entity().name else { return nil }
guard M.entity().propertiesByName[kvp.0] != nil else { Assert("\(name) does not have \(kvp.0)"); return nil }
let fetchRequest = NSFetchRequest<M>(entityName: name)
fetchRequest.predicate = NSPredicate(format: "\(kvp.0) == %@", kvp.1)
do {
let object = try context.fetch(fetchRequest)
if let foundObject = object.first { return foundObject }
return nil
} catch {
return nil
}
}
}
我想要的语法是
MYUser.get(with: ("id", "SomeUserId"), in: context)
并从发出调用的 class 推断类型...但我不确定用什么来代替这里的泛型
NSFetchRequest<M>(entityName: name)
NSFetchRequest<???>(entityName: name)
提前致谢
如果不介意写两次MYUser
,可以去掉type
参数,指定类型,这样Swift就可以推断出M
:
extension NSManagedObject {
static func get<M: NSManagedObject>(with kvp: (String, CVarArg), in context: NSManagedObjectContext) -> M? {
guard let name = entity().name else { return nil }
guard M.entity().propertiesByName[kvp.0] != nil else {
print("\(name) does not have \(kvp.0)")
return nil
}
let fetchRequest = NSFetchRequest<M>(entityName: name)
fetchRequest.predicate = NSPredicate(format: "\(kvp.0) == %@", kvp.1)
do {
let object = try context.fetch(fetchRequest)
if let foundObject = object.first { return foundObject }
return nil
} catch {
return nil
}
}
}
// usage:
let user: MYUser? = MYUser.get(with: ("id", "SomeUserId"), in: context)
如果你不想写MYUser
两次,那我想不出任何解决办法。如果 NSManagedObject
是一个协议,你可以在那里使用 Self
。
基于linkPassing generic Class as argument to function in swift suggested by Martin R
protocol Managed where Self: NSManagedObject { }
extension Managed where Self: NSManagedObject {
static func get(with kvp: (String, CVarArg), in context: NSManagedObjectContext) -> Self? {
guard let name = entity().name else { return nil }
guard entity().propertiesByName[kvp.0] != nil else { Assert("\(name) does not have \(kvp.0)"); return nil }
let fetchRequest = NSFetchRequest<Self>(entityName: name)
fetchRequest.predicate = NSPredicate(format: "\(kvp.0) == %@", kvp.1)
do {
let object = try context.fetch(fetchRequest)
if let foundObject = object.first { return foundObject }
return nil
} catch {
return nil
}
}
我有一个扩展 NSManagedObject
的静态函数来获取这样的对象...
NSManagedObject.get(type: MYUser.self, with: ("id", "SomeUserId"), in: context)
extension NSManagedObject {
static func get<M: NSManagedObject>(type: M.Type, with kvp: (String, CVarArg), in context: NSManagedObjectContext) -> M? {
guard let name = entity().name else { return nil }
guard M.entity().propertiesByName[kvp.0] != nil else { Assert("\(name) does not have \(kvp.0)"); return nil }
let fetchRequest = NSFetchRequest<M>(entityName: name)
fetchRequest.predicate = NSPredicate(format: "\(kvp.0) == %@", kvp.1)
do {
let object = try context.fetch(fetchRequest)
if let foundObject = object.first { return foundObject }
return nil
} catch {
return nil
}
}
}
我想要的语法是
MYUser.get(with: ("id", "SomeUserId"), in: context)
并从发出调用的 class 推断类型...但我不确定用什么来代替这里的泛型
NSFetchRequest<M>(entityName: name)
NSFetchRequest<???>(entityName: name)
提前致谢
如果不介意写两次MYUser
,可以去掉type
参数,指定类型,这样Swift就可以推断出M
:
extension NSManagedObject {
static func get<M: NSManagedObject>(with kvp: (String, CVarArg), in context: NSManagedObjectContext) -> M? {
guard let name = entity().name else { return nil }
guard M.entity().propertiesByName[kvp.0] != nil else {
print("\(name) does not have \(kvp.0)")
return nil
}
let fetchRequest = NSFetchRequest<M>(entityName: name)
fetchRequest.predicate = NSPredicate(format: "\(kvp.0) == %@", kvp.1)
do {
let object = try context.fetch(fetchRequest)
if let foundObject = object.first { return foundObject }
return nil
} catch {
return nil
}
}
}
// usage:
let user: MYUser? = MYUser.get(with: ("id", "SomeUserId"), in: context)
如果你不想写MYUser
两次,那我想不出任何解决办法。如果 NSManagedObject
是一个协议,你可以在那里使用 Self
。
基于linkPassing generic Class as argument to function in swift suggested by Martin R
protocol Managed where Self: NSManagedObject { }
extension Managed where Self: NSManagedObject {
static func get(with kvp: (String, CVarArg), in context: NSManagedObjectContext) -> Self? {
guard let name = entity().name else { return nil }
guard entity().propertiesByName[kvp.0] != nil else { Assert("\(name) does not have \(kvp.0)"); return nil }
let fetchRequest = NSFetchRequest<Self>(entityName: name)
fetchRequest.predicate = NSPredicate(format: "\(kvp.0) == %@", kvp.1)
do {
let object = try context.fetch(fetchRequest)
if let foundObject = object.first { return foundObject }
return nil
} catch {
return nil
}
}