我正在使用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()
}
}
从技术上讲,只要我的应用加载socket
,就不能为零,否则会崩溃。我找到了两个可以解决这个问题的解决方案
懒惰
lazy var socket = SocketIOClient(socketURL: URL(string: mainURL)!, config: [.log(false), .compress, .connectParams(["token": "asdasdasdsa"])])
使用此方法socket
将永远不会为零,因为它将始终初始化。但是这个方法的问题在于,如果创建SocketIOClient并不便宜,那么它将是一个很好的使用方法。
初始化()
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"])])
}
}
通过使用这种方法,我有点困惑,因为我最初没有像
那样创建SocketIOManager对象let socket = SocketIOManager()
因为如果我没有弄错,如果只创建了对象,套接字将被初始化,而我不确定在Singleton设计中使用init()
哪种方法适合我的用例?
答案 0 :(得分:5)
在Swift全局变量中,默认情况下,类的静态成员都是 lazy ,所以这是正确的:
this
请注意init上的 private ,以防止其他人尝试实例化此类,因为它是一个单例。
答案 1 :(得分:1)
存储类型属性在首次访问时会被懒惰地初始化。它们只保证初始化一次,即使同时由多个线程访问,也不需要使用延迟修饰符进行标记。
建议的方法是将套接字声明为非可选,首先初始化该属性,然后调用super
class SocketIOManager: NSObject {
static let sharedInstance = SocketIOManager()
let socket: SocketIOClient
init() {
socket = SocketIOClient(socketURL: URL(string: mainURL)!, config: [.log(false), .compress, .connectParams(["token": "asdasdasdsa"])])
super.init()
}
}
或者使用闭包初始化socket
,但这要求不能访问同一类的其他属性。
class SocketIOManager: NSObject {
static let sharedInstance = SocketIOManager()
let socket: SocketIOClient = {
return SocketIOClient(socketURL: URL(string: "https://server.com/path")!, config: [.log(false), .compress, .connectParams(["token": "asdasdasdsa"])])
}()
}
或者如果mainURL
在同一个类中声明为常量,则可以懒惰地初始化socket
。这意味着套接字也将在 首次访问时初始化。
class SocketIOManager: NSObject {
static let sharedInstance = SocketIOManager()
let mainURL = URL(string: "https://server.com/path")!
lazy var socket: SocketIOClient = {
return SocketIOClient(socketURL: mainURL, config: [.log(false), .compress, .connectParams(["token": "asdasdasdsa"])])
}()
}
在第二种和第三种情况下,不需要额外的init
方法。