将NSData复制到int32_t变量中

时间:2012-08-08 22:51:06

标签: iphone ios nsdictionary

我有一个很大的NSDictionary,其中包含所有NSData类型的条目。我有几个条目需要是int32_t类型但是我不是100%确定如何复制NSDictionary条目中的数据..

就像执行以下操作一样简单 -

·H

//..
int32_t myint;
}
@property (assign) int32_t myint;
//..

的.m

//..
@synthesize cardID;
//..
- (void)assignSearchData:(NSData*)searchData
{
myint = [searchData objectForKey:@"IntKey"];
}
//..

或者我的方法中是否需要某种类型的数据转换?

和一个快速的问题,我是否正确地声明了int32_t?我在文档中找到了一个例子,但是我在努力找到一个。

2 个答案:

答案 0 :(得分:1)

好吧,您可以直接访问数据对象中的原始字节。

void const *dataPtr = [data bytes];

现在你有一个指向原始内存的指针,你可以按照你想要的任何方式复制它(这些规则适用于任何数据传输,而不仅仅是iOS)。如果需要考虑对齐边界,则需要使用memcpy。

int32_t myInt;
memcpy(&myInt, dataPtr);

否则,如果在允许跨对齐边界进行整数操作的体系结构中......

int32_t myInt = *(int32_t const *)dataPtr;

现在,ARM支持跨对齐边界进行访问,但速度要慢得多。我没有进行性能比较,但是你没有继续使用错误对齐的指针,所以它可能比memcpy函数调用更好(但是,老实说,这可能是对你的性能考虑因素)。

最大的问题是数据的字节顺序。如果它是由你提供的,那就做你想做的任何事,但你应该更喜欢一个标准。

如果它来自第三方,它可能是网络字节顺序(又名big-endian)。您可能需要转换为主机端表示形式。幸运的是,htonntoh以及他们的朋友可以直接前进。

FWIW,英特尔是小端的,网络字节顺序是大端的,现代的Mac和iOS设备都是小端的,旧的Mac是大端的。

// 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];

当然,使用正确的数据初始化程序......只会在堆栈上使用那些原始字节,所以最好不要在堆栈展开后使用它。

您不必担心发送数据的对齐,除非您保证接收方数据将与某些边界对齐。

答案 1 :(得分:0)

是的,int32_t没问题。所以你有一串脚趾。你需要知道的是他的字节布局是什么。你知道数据是什么,它很容易构建它。

给定一个长度为4(大小为int32_t)的NSData对象,那么你会:

int32_t val;
if([data length] == sizeof(uint32_t)) {
    void *bytes = [data bytes];
    // if the layout is same as iOS then
    memcpy(&val, bytes, sizeof(int32_t) );
}

如果不是这样,那么你可以尝试:

unsigned char val[4] = {0,0,0,0};
if([data length] == sizeof(uint32_t)) {
    memcpy(val, bytes, sizeof(int32_t) );
    then rearrange the bytes
}