阅读 360

iOS底层探索--联合体与位域

小谷iOS底层博客合集

  • 在探索iOS底层的时候,有个程序员都不陌生的isa,isa的实现用到了 联合体位域

  • 其实在平常iOS开发中基本没有书写联合体位域的情况,,不过不代表我们可以不会啊。。我觉得到达看得懂的地步就好了!!

1. 联合体

  • 我常用到一种结构体类型 strut,有一种和结构体比较相似的结构,叫共用体,也称联合体
union 共用体名 {
    成员列表
}
复制代码
  • 联合体结构体的区别:

结构体中每个成员都会独立一块内存,相互不影响!而联合体所有成员公用一块内存!牵一而动全身!

作为一个程序员来说,还是代码比较直观!!

1.1 联合体特征1

union XGXS {
    int a;      //4个字节
    short b;    //2个字节
    char c;     //1个字节
} xgxs;

//结果
xgxs.a = 2;
xgxs.b = 4;
xgxs.c = 'c';
NSLog(@"union size: %lu - %lu",sizeof(xgxs), sizeof(union XGXS));
//union size: 4 - 4

复制代码

** 得出结论1:联合体的内存是成员所需的最大内存那个。 **

1.2 联合体特征2

xgxs.a = 2;
NSLog(@"%d---%d---%c",xgxs.a,xgxs.b,xgxs.c);//2---2---
xgxs.b = 4;
NSLog(@"%d---%d---%c",xgxs.a,xgxs.b,xgxs.c);//4---4---
xgxs.c = 'c';
NSLog(@"%d---%d---%c",xgxs.a,xgxs.b,xgxs.c);//99---99---c
复制代码

** 得出结论2:每次改变联合体中的成员,其他成员会受到影响、即联合体成员之间是相互互斥的 **

联合体的话知道这个就足够了!!

2. 位域

2.1 使用bool值证明

  • 位域的话还是比较好理解的!
  • 举个例子:假如我有一辆拖拉机!这个拖拉机的方向只能 前、后、左、右、(不能45°仰望天空哈
@interface XGTractor : NSObject
@property (nonatomic, assign) BOOL front;
@property (nonatomic, assign) BOOL back;
@property (nonatomic, assign) BOOL left;
@property (nonatomic, assign) BOOL right;
@end

@implementation XGTractor
@end


XGTractor *tractor = [[XGTractor alloc] init];
tractor.back = YES;
tractor.front = YES;
tractor.left = YES;
tractor.right = YES;

复制代码
  • 我们打印这个tractor

  • 然后我们发现了:我们可以看到 frontbackleftright各占一个字节,但其实我们只需要一个二进制就可以表现出来,也就是 0 或则 1 就可以!!

  • 这个时候我们就可以使用位域来看一下了

2.2 使用位域证明

上代码

@interface XGTractor2 : NSObject

- (void)setFront:(BOOL)isFront;
- (BOOL)isFront;
- (void)setBack:(BOOL)isBack;
- (BOOL)isBack;
- (void)setLeft:(BOOL)isLeft;
- (BOOL)isLeft;
- (void)setRight:(BOOL)isRight;
- (BOOL)isRight;

@end

#define XGDirectionFrontMask (1 << 0)
#define XGDirectionBackMask  (1 << 1)
#define XGDirectionLeftMask  (1 << 2)
#define XGDirectionRightMask (1 << 3)

@interface XGTractor2 () {
    union {
        char bits;
        struct {
            char front: 1;
            char back:  1;
            char left:  1;
            char right: 1;
        };
    } _direction;
}

@end

@implementation XGTractor2

- (instancetype)init {
    self = [super init];
    if (self) {
        _direction.bits = 0b00000000;
    }
    return self;
}
- (void)setFront:(BOOL)isFront {
    _direction.left = isFront;
}

- (BOOL)isFront {
    return !!(_direction.bits & XGDirectionFrontMask);
}

- (void)setBack:(BOOL)isBack {
    _direction.back = isBack;
}

- (BOOL)isBack {
    return !!(_direction.back & XGDirectionBackMask);
}

- (void)setLeft:(BOOL)isLeft {
    _direction.left = isLeft;
}

- (BOOL)isLeft {
    return !!(_direction.left & XGDirectionLeftMask);
}

- (void)setRight:(BOOL)isRight {
    _direction.right = isRight;
}

- (BOOL)isRight {
    return !!(_direction.left & XGDirectionLeftMask);
}

@end
复制代码
XGTractor2 *tr2 = [[XGTractor2 alloc] init];
tr2.front = 1;
tr2.back = 1;
tr2.left = 1;
tr2.right = 1;
复制代码

看结果:

这段代码的意思是:我画了个图:

基于这种结构就是位域