【问题标题】:Swift: Realm generic function with <T> like kotlinSwift:带有 <T> 的领域泛型函数,如 kotlin
【发布时间】:2019-02-19 19:40:47
【问题描述】:

我正在为领域泛型编写一个类,我已经在 Kotlin 中完成了,现在我尝试将它翻译成 swift 但它更复杂,因为 swift 似乎不如 Kotlin 灵活

有效的 Kotlin 代码:

inline fun <reified T : RealmModel> fetch(sortedBy: String,
                                          ascending: Boolean = true,
                                          noinline predicate: Query<T>? = null,
                                          completion: (error: RealmFileException?, results: List<T>?) -> Unit) {

    val sort = if (ascending) {
        Sort.ASCENDING
    } else {
        Sort.DESCENDING
    }

    try {
        val results: List<T> = if (predicate != null) {
            realm.where(T::class.java).predicate().sort(sortedBy, sort).findAll()
        } else {
            realm.where(T::class.java).sort(sortedBy, sort).findAll()
        }

        completion(null, results)
        Log.s("Successfully retrieve data (size: ${results.size}): $results")
    } catch (e: RealmFileException) {
        Log.e("ERROR: ${e.localizedMessage}")
        completion(e, null)
    }
}

上面的代码很完美。

现在这是我的 Swift 代码:

func fetch(object: Object.Type, 
           predicate: NSPredicate?, 
           sortedBy: String, ascending: Bool, 
           completion: (_ error: Error?, _ results: [Object]?) -> ()) {
    do {
        let realm = try Realm()

        let objects: Results<Object>!

        if let predicate = predicate {
            objects = realm.objects(object).filter(predicate).sorted(byKeyPath: sortedBy, ascending: ascending)
        } else {
            objects = realm.objects(object).sorted(byKeyPath: sortedBy, ascending: ascending)
        }

        let objectsArray = Array(objects)

        Log.s("Successfully retrieve data (size: \(objectsArray.count): $results")
        completion(nil, objectsArray)
    } catch let error {
        Log.e("ERROR: \(error.localizedDescription)")
        completion(error, nil)
    }
}

问题如下,在我的 swift 代码中,在完成块中,我当前返回一个 Object 类型的列表

这不适合我,我希望能够像在 kotlin 中那样给他一个类型 T 并完成返回一个类型 T 的列表,如下所示:

func get<T: Object>(completion: (_list: [T]) -> ()){
        ...
        let results = realmResults as T
        completion(results)
}

但是我有几个问题: 1 - 我无法创建这样的领域对象:realm.objects(T.type)realm.objects(T.self),我得到错误。

2 - 我不能将这样的 [Object] 列表转换为 [T] '[Object]' is not convertible to '[T]'; did you mean to use 'as!' to force downcast?

3 - 当我想像这样调用函数时 get&lt;Customer&gt;{ results in }

它不起作用cannot explicitly specialize a generic function。有什么方法可以让我的函数通用?

【问题讨论】:

  • 为了将来参考,请记住 Realm Result 是同质集合类型,因此您不能将 Object 的不同子类存储在同一个 Results 对象中。

标签: ios swift kotlin realm


【解决方案1】:

首先,将方法声明更改为当前的 Swift 语法

func get<T: Object>(completion: ([T]) -> Void) {
    // ...
}

接下来,如果您在 get 方法的闭包中指定此类型,编译器可以推断 T 的类型

get { (customers: [Customer]) -> Void in
    // ... work with `customers`
}

那么你就可以在方法中使用了

let results: Results<T>

【讨论】:

  • 谢谢帮了我很多
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-28
相关资源
最近更新 更多