我正在構建一個通用的 Realm Swift 查詢函式。我首先讓它與明確宣告的所有內容一起作業。現在我將引數移動到泛型型別中。
這是我的功能,它的作業原理是這樣的:
func queryFromCollection<T: Object>(of type: T.Type, query set: Set<UUID>, for key: String) async -> Results<T>? {
let objects = await RealmReadService.instance.readObjects(of: type)
var predicates: [NSPredicate] = []
for item in set {
let query = NSPredicate(format: "%K == %@", key, item as CVarArg)
predicates.append(query)
}
let compoundPredicate = NSCompoundPredicate(orPredicateWithSubpredicates: predicates)
return objects!.filter(compoundPredicate)
}
Setof UUIDs 轉換為CVarArg就好了。
現在,當我使用此代碼制作我的Set通用代碼時:
func queryFromCollection<T: Object, S>(of type: T.Type, query set: Set<S>, for key: String) async -> Results<T>?
在我的回圈中我必須改變item as! CVarArg. 這會編譯并運行,直到我進行查詢。
一旦我運行查詢失敗,我得到這個:“無法將型別'Foundation.UUID'(0x1df22b1e0)的值轉換為'Swift.CVarArg'(0x13b14e7b8)”
我很難理解為什么它可以將UUIDs 轉換為CVarArg當Set宣告為 aSet<UUID>而不是泛型時Set。
uj5u.com熱心網友回復:
我認為這是UUID因為NSUUID在Set<UUID>. NSUUID繼承NSObject,它確實實作了CVarArg.
但是,在泛型情況下,這種橋接不會發生,因為泛型型別不一定可以橋接。
除了讓你的函式只需要CVarArgs,
func queryFromCollection<T: Object, S: NSObject>(of type: T.Type, query set: Set<S>, for key: String) async -> Results<T>?
這將需要呼叫者進行大量顯式轉換NSUUID,我只能想到另一種相當丑陋的方式 - 制定CVarArgConvertible協議
protocol CVarArgConvertible {
func toCVarArg() -> CVarArg
}
extension UUID: CVarArgConvertible {
func toCVarArg() -> CVarArg {
self as NSUUID
}
}
// other bridgable types you want to use...
然后queryFromCollection看起來像:
func queryFromCollection<T: Object, S: CVarArgConvertible>(of type: T.Type, query set: Set<S>, for key: String) async -> Results<T>? {
// in here you would call "toCVarArg" on an element of the set to get a CVarArg.
}
或者,正如Larme在評論中提醒我的那樣,您可以使用 的另一個多載NSPredicate,它不需要CVarArgs,而是一個[Any]?:
let query = NSPredicate(format: "%K == %@", argumentArray: [key, item])
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/490181.html
標籤:IOS 迅速 仿制药 uuid nspredicate
