好吧,您可以直接访问数据对象中的原始字节。
void const *dataPtr = [data bytes];
现在您有了指向原始内存的指针,您可以随意复制它(这些规则适用于任何数据传输,而不仅仅是 iOS)。如果需要考虑对齐边界,则需要使用 memcpy。
int32_t myInt;
memcpy(&myInt, dataPtr);
否则,如果在允许跨对齐边界进行整数操作的架构上......
int32_t myInt = *(int32_t const *)dataPtr;
现在,ARM 支持跨对齐边界访问,但速度要慢得多。我没有进行性能比较,但是您不会继续使用错误对齐的指针,因此它可能比 memcpy 函数调用更好(不过,老实说,这对您来说可能是太多的性能考虑)。
最大的问题是数据的字节顺序。如果它是由您提供的,那么您可以随心所欲,但您应该更喜欢一种标准。
如果它来自第三方,它可能是网络字节顺序(又名大端)。您可能需要转换为您的主机字节序表示。hton
幸运的是,这对和ntoh
他们的朋友来说是直截了当的。
FWIW,Intel 是 little-endian,网络字节序是 big-endian,现代 Mac 和 iOS 设备是 little-endian,较旧的 Mac 是 big-endian。
// Convert from network order to host order.
// Does the right thing wherever your code is running
myInt = ntohl(myInt);
简而言之,无论...
int32_t myInt = ntohl(*(int32_t const *)[data bytes]);
或者
int32_t myInt;
memcpy(&myInt, [data bytes);
myInt = ntohl(myInt);
所以,数据必须以某种方式进入那里。是,逆...
int32_t myInt = 42;
myInt = htonl(myInt);
NSData *data = [NSData dataWithBytesNoCopy:&myInt length:sizeof(myInt) freeWhenDone:NO];
当然,使用正确的 Data 初始化器......它只会使用堆栈上的那些原始字节,所以你最好不要在堆栈展开后使用它。
您不必担心发送数据的对齐问题,除非您向接收者保证数据将与某个边界对齐。