swift 3中的单例计算属性

Posted

技术标签:

【中文标题】swift 3中的单例计算属性【英文标题】:Singleton computed property in swift 3 【发布时间】:2017-02-27 17:24:49 【问题描述】:

我试图在我的代码中实现一个单例 UIView 实例,所以每当我创建一个“MyView”实例时,nib 文件只会加载一次,然后再次重用它:

class MyView : UIView 

    @IBOutlet weak var someLabel: UILabel!
    
    static var customeView : UIView = 

        let view = Bundle.main.loadNibNamed(String(describing: MyView.self), owner: self, options: nil)?[0] as! UIView
        return view
    ()
    
    convenience init() 
        
        self.init(frame: CGRect(x: 0, y: 0, width: 576, height: 30))
        
        let viewForOnce = MyView.customeView
        viewForOnce.frame = bounds
    
 

问题是,每当我调用 MyView.customeView 时,它都会崩溃说“此类不符合键值编码”,我认为这是因为计算属性中的“所有者:自我”而发生的。

任何帮助将不胜感激。

【问题讨论】:

this class is not key value coding-compliant 通常是 Interface Builder 问题,您可以在惰性初始化属性中使用 self 我特别仔细检查了这一点,一切都已连接!我特别仔细检查了这个,一切都已连接!但如果我把 owner: MyView () 而不是 owner: self 那么它会工作! 为什么你真的需要这种行为?为什么不在 MyView 类中添加ReceiptView?顺便说一句,您所做的与单例模式无关。 我的意思是单例在我创建该类的实例时只加载一次笔尖。 ReceiptView 现在是错误的 MyView。 【参考方案1】:

问题很可能与您的ReceiptView.xib 有关。你应该先复习一下。 在 xib 中查找 IBOutlet,但不在您的 ReceiptView 类中,然后将其删除。

编辑:

我的意思是单例只加载一次笔尖 创建并实例化该类。

    不,这不会那样工作。每次调用 init 时,您的计算属性也会被调用,并且每次都会从 xib 创建一个新实例。

    正如 Carien van Zyl 已经提到的,您在 class 变量中使用 self,它对应于 MyView 类本身(或者它是子类(如果它调用子类),不是实例。尝试将nil 改为owner

    整个技术对我来说都是错误的。您不应将单例模式与 UIView 子类一起使用。 多次调用loadNibNamed 并创建完全相同的实例并没有错。如果您想在视图层次结构中多次使用同一个实例,这是不可能的,因为每个视图只能有一个超级视图。在这种情况下,您应该遵循 MVC 模式:创建多个 MyView 实例 -> 每当您更改视图中的某些内容并希望这些更改反映在其他地方时更新模型 -> 使用更新的模型更新另一个视图。

【讨论】:

我特别仔细检查了这一点,一切都已连接!但如果我把 owner: MyView () 而不是 owner: self 那么它会工作!【参考方案2】:

customeView 是一个类型属性。因此,其中的 self 将引用 MyView.self 这是一个类类型。类类型不保存实例变量,包括someLabel

见Apple's documentation on Types

【讨论】:

以上是关于swift 3中的单例计算属性的主要内容,如果未能解决你的问题,请参考以下文章

python中的单例设计模式

Python中的单例

单例在Swift 3中具有属性

swift 3中计算属性和带闭包的属性集之间的区别? [复制]

如何通过 Swift 中的闭包设置惰性计算属性的值?

Core Data 和 Swift 中的计算属性与持久存储