2017-06-23 100 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