@interface Engineer : NSObject
{
@public
union {
int bits;
struct {//位域范围(变量值范围)
int age : 3;
int level : 1;
int workers : 8;
};
}_personalInfo;
}
//- (void)setAge:(int)age;
//- (void)setLevel:(int)level;
//- (void)setWorkers:(int)workers;
- (int)getAge;
- (int)getLevel;
- (int)getWorkers;
@end
NS_ASSUME_NONNULL_END
#import "Engineer.h"
@implementation Engineer
//- (void)setAge:(int)age
//{
// self->_personalInfo.bits |= AgeMask;
//}
//
//- (void)setLevel:(int)level
//{
// self->_personalInfo.bits |= LevelMask;
//}
//
//- (void)setWorkers:(int)workers
//{
// self->_personalInfo.bits |= WorkersMask;
//}
- (int)getAge
{
return self->_personalInfo.bits & AgeMask;
}
- (int)getLevel
{
return self->_personalInfo.bits & LevelMask;
}
- (int)getWorkers
{
return self->_personalInfo.bits & WorkersMask;
}
@end
//打印
2019-10-09 11:08:14.617655+0800 SetAndGetsForMask[2630:349068] 5 0 3296
Program ended with exit code: 0
//说明
1)掩码mask既可以直接用二进制(0b开头)或十六进制(0x开头)表示,也可以左移符号<<表示(一般用于位域为1的情况);
2)掩码表示所占位数:1表示占住该位,0未占;并且所占位数应当是连续的,不存在两侧为1,中间为0的情况;
三、结论
1.arm64之后,isa是一个共用体类型的指针,存储内部套用的结构体中的所有成员变量;
2.根据结构体的位域来限制成员变量的值范围,用掩码来规定成员变量存储的位置,对掩码按位与运算取出特定位置的成员变量的值;
如:用bits对ISA_MASK按位与运算后,得到的是类(元类)对象的地址;
可以看到shiftcls成员变量位域为33位,所占bits变量的存储位置为:地位到高位第四位起,最低三位是空出来的
————因此,在arm64架构中,所有的类和元类对象地址二进制表示时最低三位都为0,十六进制表示时最低一位为0或8(这个用class和object_getClass去打印地址,此处不再展示了)!
GitHub