iOS中使用結構體與位域,大小端資料轉換
阿新 • • 發佈:2019-02-10
如何在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;
}