2017-11-18 144 views
0

我使用Socket.io库的实时功能添加到我的应用程序单的设计,和我使用Singleton设计懒VS初始化为迅速

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() 
    } 

} 

因此从技术上讲,只要我的应用程序加载up socket不能为零,否则会崩溃。我发现了两个解决方案,可以解决这个问题

  1. 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() 
    

    因为如果我没有错误的套接字将被初始化,如果只有对象被创建,我不确定abou t在单例设计中使用init()

    哪种方法适合我的用例?

    回答

    1

    在斯威夫特全局变量,包括类的静态成员默认情况下,所以这是正确的:

    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"])]) 
        } 
    } 
    

    注上的init,以防止他人试图实例化这个类的私人,因为它是一个单身人士。

    +0

    我得到这个错误'属性'self.socket'没有初始化super.init调用' – airsoftFreak

    +1

    'socket = SocketIOClient(soc ....'需要超过'super.init()',然后'编译:假设'SocketIOClient(socketURL:config)'不是failable初始值设定项。 –

    1

    documentation

    存储类型属性在他们的第一次访问延迟初始化。它们保证只被初始化一次,即使同时被多个线程访问,也不需要使用lazy修饰符进行标记。

    推荐的方法是申报插座作为非可选,首先初始化属性,然后调用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方法。

    +0

    如果'getToken()'不存在,那么它将不会建立连接,因为最初套接字被加载没有令牌如何重新初始化socket? – airsoftFreak

    +0

    没有人能读懂你的想法什么是getToken()?如果你需要一个ad hoc连接,一个singleton可能是错误的解决方案,或者你必须将套接字' var'并且根据需要创建一个新的 – vadian

    +0

    ''token“'在'.connectParams'的init函数中。 – airsoftFreak