【问题标题】:Swift inheritance of singleton pattern?单例模式的快速继承?
【发布时间】:2018-02-25 12:11:38
【问题描述】:

拥有这个从不直接使用的类,只继承:

class ApiBase {}

如何在这里定义一个通用的静态单例default? - 所以我可以:

class FooApi: ApiBase {}  // Want only one instance of `FooApi`
class BarApi: ApiBase {}  // Want only one instance of `BarApi`

FooApi.default.foo_api_only_method_name()
BarApi.default.bar_api_only_method_name()

我唯一能想到的就是创建一个protocolFooApiBarApi 需要实现。但这似乎不是最理想的,宁愿写一个像这样的实现:

func `default`<T: ApiBase>() -> T {
    if staticInstance == nil {
        staticInstance = T()
    }
    return staticInstance
}

【问题讨论】:

    标签: swift inheritance singleton swift4 swift-class


    【解决方案1】:

    我无法找到使用泛型解决此问题的方法,但我的建议是将

    static let `default` = FooApi()
    

    static let `default` = BarApi()
    

    分为两个子类。这样每个人都可以创建自己的单例,而无需太多额外的代码。

    【讨论】:

    • 这绝对是首选的解决方案。泛型在这里是错误的工具,将协议(即Self)与类继承混合是 Swift 中的潘多拉魔盒。没有理由为了避免一行清晰的代码而制造复杂性。
    • 但是超类 Singleton 应该包含一个私有 init,所以这是不可能的,对吧?
    【解决方案2】:

    最后添加了一个接口:

    protocol Instance {
        associatedtype T
        // static var _instance: T {get set}  # Can't use; can't override :(
        static func instance() -> T
    }
    

    可以这样使用:

    class ApiBase: Instance {
        var root: String = ""
    
        static var _instance: ApiBase = ApiBase()
    
        open class func instance() -> ApiBase {
            if _instance.root == "" {
                _instance = ApiBase()
            }
            return _instance
        }
    }
    

    继承:

    class FooApi: ApiBase {
        static var _fooApi: FooApi = FooApi()
    
        override class func instance() -> FooApi {
            if _fooApi.root == "" {
                _fooApi = FooApi()
            }
            return _instance
        }
    }
    

    这是次优的,因为 instance 函数的主体在模式上是相同的。但它有效。

    【讨论】:

    • 我不确定我是否遵循这个解决方案为您提供的每个子类中的静态 let 不会使用更少的代码?你能解释一下吗?我很好奇,但也很高兴你找到了解决方案。
    • 问题是,我想签约classes 以符合接口;一种要求它实现单例模式的方法。 static lets 不会让实例被重新定义。该实例需要重新定义,因为.root 值是在运行时获取的(来自UserDefaults),并且可以更改,因此我需要重新创建所有对象。同样使用您回答的static lets,不符合任何界面。
    猜你喜欢
    • 2011-05-27
    • 2017-02-11
    • 2011-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多