2017-11-18 145 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