0

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
dulan
  • 1,584
  • 6
  • 22
  • 50

3 Answers3

1

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")
    }
}
Ronny Webers
  • 5,244
  • 4
  • 28
  • 24
0

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!
Community
  • 1
  • 1
siegy22
  • 4,295
  • 3
  • 25
  • 43
0

You can follow the below option as suggested in the below url Error in Swift class: Property not initialized at super.init call - How to initialize properties which need use of self in their initializer parameter var socket: SocketIO!

Community
  • 1
  • 1
shri
  • 856
  • 1
  • 10
  • 26