在设备之间传输CGPoint的最佳方法是什么?

问题描述 投票:0回答:2

我正在快速开发基于回合的游戏,其中所有内容都必须转换为NSData。现在,我已经被困在“ NS-stuff”上很多天了。由于CGPoint不是对象而是结构,因此无法直接将其转换为NSData,因此CGPoint中的CGFloat也是如此。我正在尝试做的是:(只是一个主意,不确定是否可行。)

  1. 将CGPoint转换为2个不同的Floats
  2. 使用浮点数创建NSNummer
  3. 使用NSNumber创建NSData
  4. 将NSData转换为另一台设备中的NSNumber
  5. 将NSNumber转换为Float
  6. 将它们合并回CGPoint

这种方式太复杂了。有没有更好的方法来实施它或任何最佳做法?提前谢谢!!

PS:由于其性能,不应该考虑NSKeyedArchiver。 (不确定!)

swift nsdata nsnumber nskeyedarchiver cgpoint
2个回答
4
投票

最简单的编码CGPoint的方法是使用NSStringFromCGPointCGPointFromString。这消除了您否则将面临的所有32/64位问题。

此传输非常便宜(少于一个MTU,因此并不重要)。唯一可能会很昂贵的是字符串解析,几乎可以肯定,将其放在电线上的开销不堪重负。

但是,如果您的网络协议非常严格并且需要最佳性能,那么如果您实际上不需要非整数值,则可以将CGPoint转换为(Float32, Float32),或者更好的是将其转换为(Int32, Int32)。假设您不关心字节序,这很容易按照@robmayoff的建议进行编码。使用Int,您可以轻松地使用Int.bigEndianInt(bigEndian:)处理此问题。


1
投票

注意:如果您不需要高性能,那么Rob Napier的建议(NSStringFromCGPoint / CGPointFromString)可能会更好,因为它更容易调试。但是,许多游戏对性能的要求很高,每个游戏循环需要多个CGPoint。这些是我在这里的假设。

假设CGFloat在发送方和接收方都是相同的类型(32位或64位):

var pointToSend = CGPointMake(100, 200)
let data = NSData(bytes: &pointToSend, length: MemoryLayout<CGPoint>.size)
// send data to other device

// receive data on other device
if (data.length == MemoryLayout<CGPoint>.size) {
    var receivedPoint = UnsafePointer<CGPoint>(data.bytes).memory
} else {
    // error
}

如果接收者的CGFloat可能不同于发送者的:

typealias DoublePoint = (x: Double, y: Double)

// sender
var pointToSend = CGPointMake(100, 200)
var pairToSend = (Double(pointToSend.x), Double(pointToSend.y))
let data = NSData(bytes: &pointToSend, length: MemoryLayout.size(ofValue: pairToSend))

// receiver
if (data.length == MemoryLayout<DoublePoint>.size) {
    var receivedPair = UnsafePointer<DoublePoint>(data.bytes).memory
    var receivedPoint = CGPointMake(CGFloat(receivedPair.x), CGFloat(receivedPair.y))
} else {
    // error
}
© www.soinside.com 2019 - 2024. All rights reserved.