iOS底層原理-004 聯合體位域

聯合體與結構體的區別

  • 聯合體(union),與結構體(struct)有極為相似的語法結構,跟struct一樣可以有多種數據類型和成員
  • 結構體(struct)中所有變量是“共存”的——優點是“有容乃?”,全?;缺點是struct內存空間的分配是粗放的,不管?不?,全分配。
  • 聯合體(union)中是各變量是“互斥”的——缺點就是不夠“包容”; 但優點是內存使?更為精細靈活,也節省了內存空間
union { // 聯合體
    int I;
    double x;
    char str[16];
} myUnion;
struct {  // 結構體
    int I;
    double x;
    char str[16];
} myStruct;

位域 bit fields

位域是指信息在存儲時,并不需要占用一個完整的字節, 而只需占幾個或一個二進制位。例如在存放一個開關量時,只有0和1 兩種狀態, 用一位二進位即可。為了節省存儲空間,并使處理簡便,C語言又提供了一種數據結構,稱為“位域”或“位段”。所謂“位域”是把一個字節中的二進位劃分為幾個不同的區域, 并說明每個區域的位數。每個域有一個域名,允許在程序中按域名進行操作。 這樣就可以把幾個不同的對象用一個字節的二進制位域來表示。

驗證

  • 例如定義一個類,car,為這個car定義四個屬性,前進,后退,左轉,右轉。每一個屬性需要一個int來表示。打印初始化后占用的內存。
@interface LGCar : NSObject
@property (nonatomic,assign) int front;
@property (nonatomic,assign) int back;
@property (nonatomic,assign) int left;
@property (nonatomic,assign) int right;
@end
LGCar *p1 = [LGCar alloc];
NSLog(@"對象類型占用的內存大小:%lu",sizeof(p1));
NSLog(@"對象實際占用的內存大小:%lu",class_getInstanceSize([p1 class]));
NSLog(@"對象實際分配的內存大小:%lu",malloc_size((__bridge const void*)(p1)));
int

一共分配了32字節的內存

@interface LGCar : NSObject
 @property (nonatomic,assign) BOOL back;
@property (nonatomic,assign) BOOL left;
@property (nonatomic,assign) BOOL right;
@end

反正也是只是表示是否的屬性,那用BOOL來表示不是可以減少內存這樣下來的,換成BOOL屬性再輸出一下


BOOL

明顯占用字節小了好多,因為每一個屬性都用一個字節表示

  • 那還有優化的空間么,我們知道,一個字節是8位。那如果用一位來表示一個屬性呢。這就是聯合體位域,8個屬性就可以在同一個字節里表示了
    在這里放一個 struct 和union做比較
struct {
    char front;
    char back ;
    char left   ;
    char right  ;
    char front1 ;
    char back2  ;
    char left3  ;
    char right4 ;
    
}Mystruct;
union {
    char bits;
    struct {
        char front  : 1;
        char back   : 1;
        char left   : 1;
        char right  : 1;
        char front1 : 1;
        char back2  : 1;
        char left3  : 1;
        char right4 : 1;
        
    };
} Myunion;

//輸入結果
2021-05-09 18:07:08.581506+0800 alloc流程分析[23821:2383485] 結構體占用內存‘8’;,聯合體占用內存‘1’。

由打印看出,聯合體把一個char類型的1 字節8位,每一位都利用起來了。

總結

  • 聯合體更加節省內存

位運算

a,b為整數類型
  • & 位與 兩位同時為1,結果才為1,否則結果為0。
  • | 位或 兩位只要有一個為1,其值為1,否則結果為0。
  • ~ 取反 ~1 = 0 ;~0 = 1;
  • << 左移 各二進制位全部左移若干位(左邊的二進制位丟棄,右邊補0 )
  • >> 右移 各二進制位右移若干位,左補0或者左補1得看被移數是正還是負。
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 1. 概述 今天來點概念性的東西,如果在代碼中用到位運算和聯合體位域,是不是會顯得高級一些呢?哈哈。 作為一個開發...
    iOS發呆君閱讀 534評論 0 4
  • union 共用體/聯合體 結構體和共用體的區別在于:結構體的各個成員會占用不同的內存,互相之間沒有影響;而共用體...
    答案不止一個閱讀 984評論 0 1
  • 從 isa 底層結構引入聯合體、位域 在isa底層結構分析[http://www.lxweimin.com/p/3...
    奉灬孝閱讀 644評論 0 0
  • 之前一直講述對象本質,它的底層又做了什么。 在探索對象本質之前我們需要了解一下clang Clang是一個C語言、...
    lkm_0bdc閱讀 540評論 1 2
  • 在對 OC 對象創建的探究過程中,我們發現一個很有趣的實現 isa。isa 是將對象內存空間與 class 之間聯...
    redye閱讀 846評論 2 1