-
在探索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
-
然后我们发现了:我们可以看到
front
、back
、left
、right
各占一个字节,但其实我们只需要一个二进制就可以表现出来,也就是 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.front = 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;
看结果:
这段代码的意思是:我画了个图:
基于这种结构就是位域