2012-08-08 44 views
0

我有一個很大的NSDictionary充滿了所有類型NSData的條目。我需要爲類型int32_t的但我不是100%確定如何將數據在NSDictionary中的整個條目複製..複製NSData到int32_t變量

是因爲這樣做以下簡單的幾個條目 -

.H

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

.M

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

還是我需要某種類型的數據轉換內我的方法?

和一個快速端問題,我甚至正確地宣佈int32_t?我在文檔和這裏尋找了一個例子,但我正在努力尋找一個例子。

+0

'NSData'不響應'objectForKey:'你是否要聲明一個'NSDictionary'參數? – 2012-08-08 23:04:23

+0

opps是NSDictionary是我的意思,它包含NSData的條目..這就是我困惑的地方,我會修復我的問題,使其高度可讀性 – HurkNburkS 2012-08-08 23:07:27

+0

感謝幫助傢伙我非常抱歉意外的問題不是NSData。這一切的一線是,我已經學習了將NSData傳遞給int32_t對象的技巧:)所以現在我要去了解如何將NSString轉換爲int32_t – HurkNburkS 2012-08-09 02:52:28

回答

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 
} 
+0

好吧,我會給他們一個現在試試:)感謝您的快速反應,會讓你知道我是如何得到的。 – HurkNburkS 2012-08-08 23:09:45

+0

我嘗試使用void * bytes = [data bytes]時出現警告;其中說**用'const void *'類型的表達式初始化'void *'丟棄限定符**不知道如何處理這個。 – HurkNburkS 2012-08-08 23:22:08

+1

是的,這是因爲[NSData字節]返回一個「void const *」,這意味着它指向的數據,它不希望你搞砸。把它改爲「void const * bytes = [data bytes]」 – 2012-08-08 23:30:47

0

好,您可以直接訪問數據對象中的原始字節。

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和他們的朋友。英特爾是小端,網絡字節順序是大端,現代的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]; 

當然,使用正確的數據初始化......一個只會使用堆棧上的原始字節,所以你最好不要堆解開後使用。

除非您保證接收器數據將與某個邊界對齊,否則您不必擔心要發送的數據對齊。

+0

只要我試圖在這些示例中使用memcpy,應用程序就會崩潰並出現此錯誤 ***終止應用程序,因爲未捕獲到的exceptio n'NSInvalidArgumentException',原因:' - [__ NSCFString bytes]:發送到實例的無法識別的選擇器0x2002c4f0' – HurkNburkS 2012-08-09 02:20:37

+0

該錯誤表示您將消息「字節」發送給NSString,而NSString不實現該方法。所以,即使你的對象可能是「Data *」,但它確實是一個「NSString *」你確定你應該處理一個NSData對象而不是一個NSString對象嗎?他們是兩個完全不同的,無關的課程。 – 2012-08-09 02:22:55

+0

是的...耶穌..我想也許在我的NSDictionary條目現在是字符串,而不是數據...它已經很長時間,因爲我做了字典,也許我已經把它與我做的其他事情混淆了......而不是檢查...我犯了一個嚴重的錯誤..現在要檢查它並用我的發現報告。 ..... – HurkNburkS 2012-08-09 02:29:38