利用共用体union、位域存储Bool状态值
一、利用位域技术存储Bool状态值的方式可以有效的减少内存。
1)位域在结构体中的实践
定义一个匿名结构体 ,结构体占一个字节的内存大小。
struct{
// 0b0000 0000 一个字节含有8位
char old :1;//最低位(最右边开始) 一个位bit
char tall :1;
char fat :1;
};
2)由于BOOL的值只有真假两种也就是0,非0因此可以利用这个特性来做位域存储
3)通常情况定义一个Person类,里面三个BOOL属性,old、tall、fat
通常做法如下:定义三个BOOL变量_old、_tall、_fat
- (void)setFat:(BOOL)fat
{
_fat = fat;
}
那么这样做,意味着Person对象里面有1个字节存_old数据,一个字节存_tall数据,一个字节存_fat数据。总的需要3个字节来存放三个状态值。而每个字节里面存放的都是0或1,这两个数字在8位里面只需要用到最低位就够了,剩余的6个位是空余的,导致浪费。所以如果三个或者四个熟悉的状态值存储,往往可以利用一个字节三个或者四个位就能存储完成。(这个也是很多底层C语言代码的一种减少内存开销的存储方式)。
4)共用体:union,与struct类似,不同是:里面的内容公用一块内存空间,后面赋值的内容可能完全覆盖之前的其他内容赋值。union的大小取决于内容元素占用最大的那个。
5)结合union构建一个存储三种BOOL状态值的存储。(union的引入增加代码可读性,及代码简便)代码如下:
#import "HPPerson.h"
#define oldMask (1<<0)//位域运算old值的掩码
#define tallMask (1<<1)//位域运算tall值的掩码
#define fatMask (1<<2)//位域运算fat值的掩码
//Mask...
@implementation HPPerson3
{
//定义一个共用体体(1个字节大小) 利用位域来存储
union{
char bits;
//表示说明作用。增加可读性
struct{
char old :1;//oldMask最低位(最右边开始) 一个位bit
char tall :1;//tallMask
char fat :1;//fatMask
};
}_oldTallFat;
}
- (instancetype)init
{
self= [super init];
if(self) {
NSLog(@"union体大小:%lu",sizeof(_oldTallFat));
}
return self;
}
/*
1、取值:&运算
2、设值:|运算
*/
//=============设值运算========
- (void)setOld:(BOOL)old
{
if(old) {
_oldTallFat.bits |= oldMask;
}else{
_oldTallFat.bits&= (~oldMask);
}
}
- (void)setTall:(BOOL)tall
{
if(tall) {
_oldTallFat.bits |= tallMask;
}else{
_oldTallFat.bits&= (~tallMask);
}
}
- (void)setFat:(BOOL)fat
{
if(fat) {
_oldTallFat.bits |= fatMask;
}else{
_oldTallFat.bits&= (~fatMask);
}
}
//================取值==========
//0假,非0真(-1也是真)
- (BOOL)isOld
{
return !!(_oldTallFat.bits&oldMask);// !!的使用,可以巧妙转换非0的数值为BOOL值
}
- (BOOL)isFat
{
return !!(_oldTallFat.bits&fatMask);
}
- (BOOL)isTall
{
return !!(_oldTallFat.bits&tallMask);
}
@end