简体   繁体   中英

iOS swift Singleton init method

I'm writing a singleton class to access socket by adopting socket.IO-objc , here's what I did so far:

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!
    }
}

Yet the compiler complains:

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

How should I write my init method here to make the compilation error go away?

By the way, I transitioned the code above from objective-c, in obj-c, the SocketIO is initialized like so:

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

And If I put the init method this way:

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

It complains:

self used before super.init call

Is it necessary to inherit from NSObject for your application? I ran into a similar situation where I needed to set the Singleton as a delegate (so I needed self). By not inheriting from NSObject, my issue was resolved - no need to call super.init() anyway then

Apple's recommendation for a Singleton is like this :

If you need to perform additional setup beyond initialization, you can assign the result of the invocation of a closure to the global constant:

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

But a (I think) more recent syntax can also be found on their swift blog , which I prefer :

class Singleton {
    static let sharedInstance = Singleton()

    private init() {
        // do your init here
        print("Singleton created")
    }
}

Quote from The Swift Programming Language, which answers your question:

“Swift's compiler performs four helpful safety-checks to make sure that two-phase initialization is completed without error:”

Safety check 1 “A designated initializer must ensure that all of the “properties introduced by its class are initialized before it delegates up to a superclass initializer.”

Excerpt From: Apple Inc. “The Swift Programming Language.” iBooks. https://itunes.apple.com/us/book/swift-programming-language/id881256329?mt=11

Credits: Ruben on this question

Another solution is to make the 'socket' variable unwrapped optional.

var socket:IOSocket!

您可以按照以下URL中建议的以下选项执行Swift类中的以下URL 错误:在super.init调用中未初始化属性-如何在其初始值设定项参数 var socket中初始化需要使用self的属性 :SocketIO!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM