Lazy vs init用于swift中的单例设计

air*_*eak 1 ios socket.io swift

我正在使用Socket.io库为我的应用程序添加实时功能,而我正在使用Singleton设计

import SocketIO

class SocketIOManager: NSObject {

    static let sharedInstance = SocketIOManager()

    var socket: SocketIOClient!

    func establishConnection() {
       socket = SocketIOClient(socketURL: URL(string: mainURL)!, config: [.log(false), .compress, .connectParams(["token": "asdasdasdsa"])])
       socket.connect()

    }

    func closeConnection() {
        socket.disconnect()
    }

}
Run Code Online (Sandbox Code Playgroud)

因此,技术上每当我的应用程序加载时socket不能为零,否则它将崩溃.我找到了两个可以解决这个问题的解决方案

  1. lazy var socket = SocketIOClient(socketURL: URL(string: mainURL)!, config: [.log(false), .compress, .connectParams(["token": "asdasdasdsa"])])
    
    Run Code Online (Sandbox Code Playgroud)

通过使用此方法socket将永远不会为零,因为它将始终初始化.但是这个方法的问题在于,如果创建SocketIOClient并不便宜,那么它将是一个很好的使用方法.

  1. 在里面()

    class SocketIOManager: NSObject {
    
        static let sharedInstance = SocketIOManager()
    
        let socket: SocketIOClient!
    
    
    
    init() {
            super.init()
            socket = SocketIOClient(socketURL: URL(string: mainURL)!, config: [.log(false), .compress, .connectParams(["token": "asdasdasdsa"])])
      }
    }
    
    Run Code Online (Sandbox Code Playgroud)

通过使用这种方法,我有点困惑,因为我最初没有创建像SocketIOManager对象

let socket = SocketIOManager()
Run Code Online (Sandbox Code Playgroud)

因为如果我没有弄错,如果只创建了对象,套接字将被初始化,而我不确定init()在Singleton设计中使用

哪种方法适合我的用例?

Jos*_*ann 5

在Swift全局变量中,默认情况下包括类的静态成员都是惰性的,所以这是正确的:

class SocketIOManager: NSObject {

    static let sharedInstance = SocketIOManager()

    let socket: SocketIOClient!

    private override init() {
        super.init()
        socket = SocketIOClient(socketURL: URL(string: mainURL)!, config: [.log(false), .compress, .connectParams(["token": "asdasdasdsa"])])
  }
}
Run Code Online (Sandbox Code Playgroud)

注意init上的private,以防止其他人试图实例化这个类,因为它是一个单例.