1. 程式人生 > >iOS中使用結構體與位域,大小端資料轉換

iOS中使用結構體與位域,大小端資料轉換

如何在iOS中使用結構體資料型別

在定義結構體時,如果不涉及到OC中的物件時,可以直接將結構體當作成員變數屬性使用,一旦在結構中定義了OC中的物件,編譯會報錯,提示“ARC時禁止在結構體中定義OC的物件”,主要原因在於ARC無法管理結構體中的OC物件的生命週期以記憶體。可以從以下幾個方面分析:

  • ARC在是編譯器特性,編譯時在合適的位置插入物件的記憶體管理程式碼。由於標準的C語言結構體struct沒有解構函式,編譯器無法在合適的位置插入記憶體管理程式碼,從而導致記憶體洩漏。因此在ARC專案中,如果沒有做特殊處理,在結構體中不能宣告OC物件,除非明確指出放棄對該物件的記憶體管理許可權,例如將物件定義為 __unsafe_unretain
  • 在定義結構體時,成員變數全部用基本資料型別,不引入OC物件
  • ARC專案不支援,但是非ARC專案支援,可以在定義結構體的編譯檔案上加上 -fno-objc-arc編譯選項
  • 在定義物件時,宣告放棄對該物件的記憶體管理許可權,類似於 __unsafe_unretain UIView *customView ,儘管如此,這種做法有可能使得在引用物件時,該物件已經釋放,導致莫名的錯誤
  • 可以建立一個類來代替結構體

如何在結構體中使用位域

位域定義如下:

typedef struct {
    unsigned int second: 6;
    unsigned int minute: 6;
    unsigned int hour: 5;
    unsigned int day:5;
    unsigned int month :4;
    unsigned int year: 6;
}testStruct;

位域的定義形式為:型別說明符號 位域名:位域長度
這裡的位域長度單位是 bit 位,而不是位元組數,正因為如此,在某些記憶體要求比較高的場景中,通過位域可以節省一定的記憶體。
注意:位域是從低位向最高位分配記憶體的

大端資料與小端資料

大端對齊資料(網路順序)

資料的高位元組儲存在記憶體的低地址中,而資料的低位元組儲存在記憶體的高地址中,這樣的儲存模式有點兒類似於把資料當作字串順序處理:地址由小向大增加,而資料從高位往低位放;這和我們的閱讀習慣一致。

小端對齊資料(主機順序)

資料的高位元組儲存在記憶體的高地址中,而資料的低位元組儲存在記憶體的低地址中,這種儲存模式將地址的高低和資料位權有效地結合起來,高地址部分權值高,低地址部分權值低。(簡單的來說就是反過來存放資料了)

在iOS中可以通過 ntohl(x) 與 htonl(x) 函式實現大小端資料之間的轉換,net to host long(返回值) 或者 host to net long(返回值)

- (NSData *)intNetToHostdata:(int)i {
    //  網路到主機順序 (轉換成小端資料)
    int j = ntohl(i);
    NSData *data = [NSData dataWithBytes:&j length:sizeof(i)];
    return data;
}