HTML5   发布时间:2022-04-27  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了ios – 我可以使用Realm Results类将协议用作泛型吗?大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我想创建两个Realm模型类和一个协议,它由两个模型类采用.例如:

class Dog: Object,Animal {
    dynamic var name = ""
}
class Cat: Object,Animal {
    dynamic var name = ""
}
protocol Animal {
    var name: String { get }
}

在这种情况下,我创建了两个模型类和一个协议.

但是,当我转移到实现时,问题就出现了.下面的代码是在视图控制器中编写的:

var dogs: Results<Dog>? {
    return try! Realm().objects(Dog)
}
var cats: Results<Cat> {
    return try! Realm().objects(Cat)
}

这段代码没有任何问题.但是下面的代码

var animals: Results<Animal>? {
    switch currentSegmented { // this is from UISegmentedControl
    case .Cat:  // this is from enum
        return self.cats
    case .Dog:
        return self.dogs
}

未编译错误:结果要求Animal继承自Object.

但是,Animal是一个协议,因此不能从Object继承.

这里仍然可以使用协议吗?

解决方法

我不认为有一个很好的解决方案. Swift中用户定义的泛型是不变的,所以即使Animal是一个类,你也无法转换结果< Dog>结果< Animal>.

令人不快的详细解决方案是围绕不同类型的结果创建一个显式的包装器类型:

enum AnimalResultsEnum {
    case DogResults(dogs: Results<Dog>)
    case CatResults(cats: Results<Cat>)
}

class AnimalResults {
    var animals = AnimalResultsEnum.DogResults(dogs: try! Realm().objects(Dog))

    var realm: Realm? {
        switch animals {
        case .DogResults(let dogs):
            return dogs.realm
        case .CatResults(let cats):
            return cats.realm
        }
    }

    var count: Int {
        switch animals {
        case .DogResults(let dogs):
            return dogs.count
        case .CatResults(let cats):
            return cats.count
        }
    }

    subscript(index: int) -> Animal {
        switch animals {
        case .DogResults(let dogs):
            return dogs[index]
        case .CatResults(let cats):
            return cats[index]
        }
    }

    // ... wrap the rest of the methods needed ...
}

你可以通过创建一个半类型擦除容器来包装结果来制作这个通用:

class CovariantResults<T: Object> {
    private var base: _CovariantResultsBase<T>

    init<U: Object>(_ inner: Results<U>) {
        base = _CovariantResultsImpl<T,U>(inner)
    }

    subscript(index: int) -> T {
        return base[index]
    }

    // ... wrap the rest of the methods needed ...
}

class _CovariantResultsBase<T: Object> {
    subscript(index: int) -> T { fatalError("abstract") }
    // ... wrap the rest of the methods needed ...
}

class _CovariantResultsImpl<T: Object,U: Object>: _CovariantResultsBase<T> {
    private let impl: Results<U>

    init(_ inner: Results<U>) {
        impl = inner
    }

    override subscript(index: int) -> T {
        return impl[index] as! T
    }

    // ... wrap the rest of the methods needed ...
}

// Used as:
let animals = CovariantResults<Animal>(try! Realm().objects(Dog))

大佬总结

以上是大佬教程为你收集整理的ios – 我可以使用Realm Results类将协议用作泛型吗?全部内容,希望文章能够帮你解决ios – 我可以使用Realm Results类将协议用作泛型吗?所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。