2009-11-05 52 views
3

我是Objective-C(和C本身)的新手,需要從HTTP輸出中使用NSData。我從來沒有真正使用過字節數組,或者不必擔心小/大端問題,並且努力編寫以下方法來讀取NSNumber,該指定長度爲NSData從NSData中讀取NSNumber

- (NSNumber *)readNumberWithLength:(NSUInteger)length 
{ 
    Byte k[length]; 
    [data getBytes:k range:NSMakeRange(offset, length)]; // big endian byte array representing a number 
    offset += length; 

    NSNumber *number; 
    if (length==4) { 
     number = [NSNumber numberWithUnsignedInt:CFSwapInt32BigToHost(*(uint32_t *)k)]; 
    } else if (length==2) { 
     number = [NSNumber numberWithUnsignedShort:CFSwapInt16BigToHost(*(uint16_t *)k)]; 
    } else if (length==1) { 
     number = [NSNumber numberWithUnsignedChar:*(uint8_t *)k]; 
    } else if (length==8) { 
     number = [NSNumber numberWithUnsignedLongLong:CFSwapInt64BigToHost(*(uint64_t *)k)]; 
    } else { 
     number = [NSNumber numberWithInt:0]; 
    } 

    return number; 
} 

我有NSData *dataNSUInteger offset聲明爲實例變量。

此編碼是否正確?有什麼我應該擔心的嗎?我還沒有在實際的設備上測試過它(僅在模擬器上),它似乎對我來說工作得很好。你有什麼意見嗎?

謝謝!

回答

2

該代碼看起來或多或少是正確的。

似乎很難。

我會驚訝 - 並不完全震驚,但感到驚訝 - 從HTTP服務器返回的數據實際上只是原始字節。這是非常罕見的,並且在這種情況下,服務器的設計幾乎肯定是錯誤的。 (當然有些情況下二進制HTTP響應是正確的答案,但它非常罕見)。

除非你正在談論數據中數以千計的值,否則HTTP隱含的開銷幾乎肯定會超過二進制的任何收益。從字符串中解析已知的數字值不是,即繁重,除非您確實在不斷地這樣做(這會使HTTP首先不是特別有吸引力)。


服務器設計:不夠公平。處理這個問題的另一個有效理由是因爲你無法改變這個難題的特定部分。

我會親自執行代碼的防守:

  • 驗證本地數據大小的預期大小相比,遠程/網絡規模,以防止意外(這可能是在初始化或斷言一些調試代碼 - 我喜歡在這種情況下保持防禦)。

  • 使用case語句而不是if/else if/else if/else序列。完全是一個審美決定,但它有助於...

  • ...處理length是一個意外的值通過日誌記錄,即使只在調試模式。我認爲意想不到的價值規模對整體正確性可能會非常糟糕?

+0

這是一個RESTful API,它真的回答收藏與數百個值(字符串和數字)的。輸出是gziped的,所以它對我有意義。我沒有真正設計服務器,它不會改變,所以我更擔心,如果我的實施是正確的。你認爲有更好的方法來做到這一點?謝謝! – leolobato 2009-11-05 18:41:59

+0

感謝您的提示!我實際上擔心我是如何將字節數組轉換爲nsnumber的,但由於您沒有提到該部分,所以看起來是正確的(或者至少是一種有效的方式)。 :) – leolobato 2009-11-06 15:20:50