【问题标题】:Protocol defining singleton with properties使用属性定义单例的协议
【发布时间】:2018-07-05 20:09:27
【问题描述】:

我有以下协议,它定义了一个带有属性的单例:

protocol SingletonProtocol {
    static var shared: SingletonProtocol { get }
    var variable : Int { get set }
}

以及实现此协议的以下类:

class Singleton : SingletonProtocol{
    static let shared : SingletonProtocol = Singleton()
    var variable = 4
}

如果我打电话:

Singleton.shared.variable = 5

我收到以下错误:

 change 'let' to 'var' to make it mutable

如果我在没有协议的情况下实现这个类,我不会收到错误,并且可以更改变量。我可以通过添加setVariable: 方法来解决这个问题,但我想直接访问和修改变量。

如何编写一个协议来定义一个带有可修改变量的单例?

【问题讨论】:

  • 您不能真正确保符合标准的类型只有一个单例实例,因为为此您需要在您的类中声明一个私有初始化程序,您可以这样做,但您不能在SingletonProtocol 中声明它,这样一个类就可以符合您的协议,而无需只有一个单例实例。使用您当前的实现,可以实例化任意数量的 Singleton 实例。
  • 谢谢@DávidPásztor 的评论,有没有办法让协议在其令人欣慰的协议中“强制”私有初始化。
  • 很遗憾,您不能将协议方法标记为私有。
  • 你可以设置成var shared = Singleton.shared shared.variable = 5
  • 我很好奇,这里为什么需要一个协议?还有哪些其他类型符合SingletonProtocol?

标签: swift singleton protocols


【解决方案1】:

使协议仅可用于类(结构将无法符合此协议):

protocol SingletonProtocol: AnyObject {
    static var shared: SingletonProtocol { get }
    var variable: Int { get set }
}

现在您可以将 shared 属性设置为 let

class Singleton: SingletonProtocol {
    static let shared: SingletonProtocol = Singleton()
    var variable: Int = 0
}

【讨论】:

  • 在你的课堂上,别忘了将你的初始化设为私有
  • 1) 使用私有集时出现错误“无法分配给属性:'共享' setter 无法访问”2) 仅用于类对我有何帮助?
  • 对不起,我的错误;这个问题与结构有关,结构是值类型;我改变了答案。如果一个协议仅适用于类,则意味着只有引用类型才能符合它;引用类型可以是不可变的,即使它的成员不是。所以现在你可以用 let 代替 var
  • 如果我这样做了,该类将不再是单例,shared 必须是不可变的。
  • 我正在 Playground 中进行测试,它对我很有用,swift 4.1
【解决方案2】:

改变

static let shared : SingletonProtocol = Singleton()

到

static var shared : SingletonProtocol = Singleton()
private init() {} 

【讨论】:

  • 如果我这样做,该类将不再是单例,共享必须是不可变的。
  • 如果您添加private init() {},那么对于多个实例的潜力应该不会太大。
  • 变量如何保持不可变?
  • 好点。但是,一旦初始设置,您将如何在上述情况下更改它?
【解决方案3】:

在您的单例类中,将变量声明从 let 更改为 var。所以这将与协议声明中的相同。

class Singleton : SingletonProtocol{
    static var shared : SingletonProtocol = Singleton()
    var variable = 4
}

编辑:

还在协议声明中只为 sharedInstance 添加 getter 以作为单例类的用途:

protocol SingletonProtocol: AnyObject {
    static var shared: SingletonProtocol { get }
    var variable: Int { get set }
}

【讨论】:

  • 如果我这样做了,该类将不再是单例,shared 必须是不可变的。
  • @amir 检查上面汤姆的评论,这里也可以适用。
  • 是的,但我仍然希望共享被让,因为它是写单例的正确方式,所以正确的解决方案是 Rico Crescenzio 的
猜你喜欢
  • 2014-02-16
  • 1970-01-01
  • 2015-06-04
  • 1970-01-01
  • 2019-12-16
  • 1970-01-01
  • 1970-01-01
  • 2017-08-24
  • 1970-01-01
相关资源
最近更新 更多