2017-06-23 54 views
0

我正在通過從https://github.com/nickyhuyskens/SwiftCocoaAsyncSocketTutorial下載的Swift 2可可異步套接字教程工作它是在Swift 2中編寫的,我正在使用Xcode 8/Swift 3。似乎相當不錯,除了一個地方,我似乎無法進行必要的修正,只有幾次修正。可可異步套接字教程代碼從Swift 2轉換到Swift 3

原始斯威夫特2代碼:

func socket(_ sock: GCDAsyncSocket!, didRead data: Data!, withTag tag: Int) 
{ 
    if tag == 1 { 
     var bodyLength: Int16 = 0 
     data.getBytes(&bodyLength, length: sizeof(Int16)) 
     print("Header received with bodylength: \(bodyLength)") 
     socket.readDataToLength(UInt(bodyLength), withTimeout: -1, tag: 2) 
    } else if tag == 2 {    
     let packet = NSKeyedUnarchiver.unarchiveObjectWithData(data) as! Packet 
     PacketHandler.HandlePacket(packet) 
     socket.readDataToLength(UInt(sizeof(Int16)), withTimeout: -1, tag: 1) 
     socket.readData(toLength: UInt(MemoryLayout<Int16>.size), withTimeout: -1, tag: 1) 
    } 
} 

我的斯威夫特3個變化:

func socket(_ sock: GCDAsyncSocket!, didRead data: Data!, withTag tag: Int) { 
    if tag == 1 { 
        var bodyLength: UInt16 = 0 
     bodyLength = (UInt16(MemoryLayout<Data>.size)) 
     print("Header received with bodylength: \(bodyLength)") 
     socket.readData(toLength: UInt(bodyLength), withTimeout: -1, tag: 2) 
    } else if tag == 2 { 
     let packet = NSKeyedUnarchiver.unarchiveObject(with: data) as! Packet 
     PacketHandler.HandlePacket(packet) 
     socket.readData(toLength: UInt(MemoryLayout<Int16>.size), withTimeout: -1, tag: 1) 
    } 
} 

當它到達線

let packet = NSKeyedUnarchiver.unarchiveObject(with: data) as! Packet 

結果是一個「致命的錯誤:意外在解包可選值時發現零「。我一直在尋找涉及Swift 3中變化的帖子,以獲取「sizeof」數據,但我不確定對「MemoryLayout」的更改是否正確。此外,我已經嘗試了許多涉及使用NSKeyedUnarchiver.unarchiveObjectWithData功能的Swift 3更改的更改,但這些更改也沒有提供可行的解決方案。

任何幫助或指向轉換解決方案的地方將不勝感激。

+0

請,請,請停止使用'!'迫使展開的對象。這個錯誤是由於你強制展開對象並且沒有正確處理這些對象可能是'nil'的事實而引起的。你的對象應該是可選的或非空的。如果您繼續使用'!',您將繼續遇到像這樣的崩潰。這不是安全的代碼。 – AdamPro13

回答

0
print(MemoryLayout<Data>.size == 8) 

打印

true 

你確定這是你有什麼期望?它是數據類型的大小,而不是存儲的字節數。

數據的大小(例如)

let data = Data(bytes: [1,2,3,4,5,6,7,8,9,0]) 
print(data.count) 

打印

10 
+0

感謝您的迴應 - 我一定在查找套接字數據包的第二部分中存儲的字節數。然後,該數據包必須在標記== 2段中「未封裝」,並使用「NSKeyedUnarchiver.unarchiveObject(with:data)」過程恢復原始對象。 Swift 3的處理方式似乎發生了重大變化,甚至在進行了一些研究和閱讀之後,我也不完全清楚如何讓Swift 3正確處理這個問題。在此先感謝幫助。 – FlapJack