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

时间:2014-09-07 20:46:28

标签: swift nsdata nsnumber nskeyedarchiver cgpoint

我正在使用swift开发一个回合制游戏,其中所有内容都必须转换为NSData。现在我一直被困在" NS-stuff"很多天因为CGPoint不是对象而是结构,所以它不能直接转换为NSData,CGPoint中的CGFloat也是如此。我想做的是:(只是一个想法,不确定它是否有效。)

  1. 将CGPoint转换为2个不同的Floats
  2. 使用Float创建NSNummer
  3. 使用NSNumber创建NSData
  4. 将NSData转换回另一台设备的NSNumber
  5. 将NSNumber转换为Float
  6. 将它们合并回CGPoint
  7. 这种方式太复杂了。 有没有更好的方法来实现它或任何最佳实践?在此先感谢!!!

    PS:NSKeyedArchiver不应该因为它的性能而被考虑。 (不确定!)

2 个答案:

答案 0 :(得分:3)

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

这种运输非常便宜(少于一个MTU,因此它并不重要)。唯一可能是昂贵的是字符串解析,这几乎肯定会被放在线上的成本所淹没。

但是,如果您的网络协议非常紧凑并且需要最佳性能,我会将CGPoint转换为(Float32, Float32),或者更好的是(Int32, Int32),如果您没有&#39} ; t实际上需要非整数值。 @robmayoff很容易编码,假设您不关心字节序。使用Int,您可以轻松地使用Int.bigEndianInt(bigEndian:)来处理此问题。

答案 1 :(得分:1)

注意:如果你不需要高性能,你可能会更好地使用Rob Napier的建议(NSStringFromCGPoint / CGPointFromString),因为它更简单,更容易调试。但是,许多游戏都有很高的性能要求,每个游戏循环需要不止一个CGPoint。这些是我的假设。

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

var pointToSend = CGPointMake(100, 200)
let data = NSData(bytes: &pointToSend, length: sizeof(CGPoint))
// send data to other device

// receive data on other device
if (data.length == sizeof(CGPoint)) {
    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: sizeofValue(pairToSend))

// receiver
if (data.length == sizeof(DoublePoint)) {
    var receivedPair = UnsafePointer<DoublePoint>(data.bytes).memory
    var receivedPoint = CGPointMake(CGFloat(receivedPair.x), CGFloat(receivedPair.y))
} else {
    // error
}