【问题标题】:iOS swift Singleton init methodiOS swift Singleton 初始化方法
【发布时间】:2015-04-07 06:38:39
【问题描述】:

我正在编写一个通过采用socket.IO-objc 来访问套接字的单例类,这是我目前所做的:

class Singleton_SocketManager: NSObject, SocketIODelegate {
    var isSocketConnected: Bool = false
    var socket: SocketIO

    override init() {
        super.init()
    }

    class var sharedInstance: Singleton_SocketManager {
        struct Static {
            static var onceToken: dispatch_once_t = 0
            static var instance: Singleton_SocketManager? = nil
        }
        dispatch_once(&Static.onceToken) {
            Static.instance = Singleton_SocketManager()
        }
        return Static.instance!
    }
}

然而编译器抱怨:

Property 'self.socket' not initialized at super.init call

我应该如何在此处编写我的 init 方法以使编译错误消失?

顺便说一下,我上面的代码是从objective-c转过来的,在obj-c中,SocketIO是这样初始化的:

    self.socket = [[SocketIO alloc] initWithDelegate:self];

如果我这样放置 init 方法:

    override init() {
    self.socket = SocketIO(delegate: self)
    super.init()
}

它抱怨:

self used before super.init call

【问题讨论】:

    标签: ios sockets swift singleton


    【解决方案1】:

    您的应用程序是否需要从 NSObject 继承?我遇到了类似的情况,我需要将 Singleton 设置为委托(所以我需要 self)。通过不从 NSObject 继承,我的问题得到了解决 - 无论如何都不需要调用 super.init()

    Apple's 对单身人士的推荐是这样的:

    如果您需要在初始化之外执行其他设置,您可以将调用闭包的结果分配给全局常量:

    class Singleton {
        static let sharedInstance: Singleton = {
            let instance = Singleton()
            // setup code
            return instance
        }()
    }
    

    但是(我认为)更新的语法也可以在他们的 swift blog 上找到,我更喜欢:

    class Singleton {
        static let sharedInstance = Singleton()
    
        private init() {
            // do your init here
            print("Singleton created")
        }
    }
    

    【讨论】:

      【解决方案2】:

      【讨论】:

        【解决方案3】:

        引自 The Swift Programming Language,它回答了你的问题:

        “Swift 的编译器会执行四项有用的安全检查,以确保 两阶段初始化完成,没有错误:”

        安全检查 1 “指定的初始化程序必须确保所有 “由它的类引入的属性在它之前被初始化 委托给一个超类初始化器。”

        摘自:Apple Inc. “Swift 编程语言”。电子书。 https://itunes.apple.com/us/book/swift-programming-language/id881256329?mt=11

        致谢:Rubenthis question

        另一种解决方案是将“socket”变量解包为可选。

        var socket:IOSocket!
        

        【讨论】:

        • @dulan 为什么不将 'socket' 变量设为可选?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-07-29
        • 1970-01-01
        • 2014-12-29
        • 2020-06-22
        相关资源
        最近更新 更多