要想学习Runtime,首先要了解它底层的一些常用数据结构,比如isa指针
在arm64架构之前,isa就是一个普通的指针,存储着Class、Meta-Class对象的内存地址
从arm64架构开始,对isa进行了优化,变成了一个共用体(union)结构,还使用位域来存储更多的信息
共用体与位域
demo:
int main(int argc, const char * argv[]) {
@autoreleasepool {
MJPerson *person = [[MJPerson alloc] init];
person.thin = YES;
person.rich = YES;
person.handsome = NO;
NSLog(@"thin:%d rich:%d hansome:%d", person.isThin, person.isRich, person.isHandsome);
}
return 0;
}
MJPerson.h
@interface MJPerson : NSObject
- (void)setTall:(BOOL)tall;
- (void)setRich:(BOOL)rich;
- (void)setHandsome:(BOOL)handsome;
- (void)setThin:(BOOL)thin;
- (BOOL)isTall;
- (BOOL)isRich;
- (BOOL)isHandsome;
- (BOOL)isThin;
@end
MJPersion.m
@interface MJPerson()
{
union {
int bits;
struct {
char tall : 1;
char rich : 1;
char handsome : 1;
char thin : 1;
};
} _tallRichHandsome;
}
@end
#define MJTallMask (1<<0)
#define MJRichMask (1<<1)
#define MJHandsomeMask (1<<2)
#define MJThinMask (1<<3)
@implementation MJPerson
- (void)setTall:(BOOL)tall
{
if (tall) {
_tallRichHandsome.bits |= MJTallMask;
} else {
_tallRichHandsome.bits &= ~MJTallMask;
}
}
- (BOOL)isTall
{
return !!(_tallRichHandsome.bits & MJTallMask);
}
- (void)setRich:(BOOL)rich
{
if (rich) {
_tallRichHandsome.bits |= MJRichMask;
} else {
_tallRichHandsome.bits &= ~MJRichMask;
}
}
- (BOOL)isRich
{
return !!(_tallRichHandsome.bits & MJRichMask);
}
- (void)setHandsome:(BOOL)handsome
{
if (handsome) {
_tallRichHandsome.bits |= MJHandsomeMask;
} else {
_tallRichHandsome.bits &= ~MJHandsomeMask;
}
}
- (BOOL)isHandsome
{
return !!(_tallRichHandsome.bits & MJHandsomeMask);
}
- (void)setThin:(BOOL)thin
{
if (thin) {
_tallRichHandsome.bits |= MJThinMask;
} else {
_tallRichHandsome.bits &= ~MJThinMask;
}
}
- (BOOL)isThin
{
return !!(_tallRichHandsome.bits & MJThinMask);
}
@end
- 共用体成员共用一块内存地址。
- 位域仅仅起到一个提示信息的作用。去掉也没有影响。
1. 小Tips方便理解
位与: 任何与0相与都是0,得到0 任何与1相与都是本身,不变
位或: 任何与1相或都是1,得到1 任何与0相或都是本身,不变
if(yes){
1.想控制的位得到1 --> 或上1
2.其他位不变 --> 或上0
}else{
1.想控制的位得到0 --> 与上 0
2.其他位不变 ---> 与上1
}
2.如果是4位,掩码就要变
union {
int bits;
struct {
char tall : 4;
char rich : 4;
char handsome : 4;
char thin : 4;
};
} _tallRichHandsome;
#define MJTallMask (1<<0)
#define MJRichMask (1<<4)
#define MJHandsomeMask (1<<8)
#define MJThinMask (1<<12)
枚举中的位运算
(void)viewDidLoad {
[super viewDidLoad];
[self setOptions: MJOptionsOne | MJOptionsFour];
[self setOptions: MJOptionsOne + MJOptionsTwo + MJOptionsFour];
// self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleTopMargin;
//
// NSKeyValueObservingOptions options = NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld;
//
// [self addObserver:self forKeyPath:@"age" options:options context:NULL];
}
typedef enum {
// MJOptionsNone = 0, // 0b0000
MJOptionsOne = 1<<0, // 0b0001
MJOptionsTwo = 1<<1, // 0b0010
MJOptionsThree = 1<<2, // 0b0100
MJOptionsFour = 1<<3 // 0b1000
} MJOptions;
/*
0b0001
0b0010
0b1000
------
0b1011
&0b0100
-------
0b0000
*/
- (void)setOptions:(MJOptions)options
{
if (options & MJOptionsOne) {
NSLog(@"包含了MJOptionsOne");
}
if (options & MJOptionsTwo) {
NSLog(@"包含了MJOptionsTwo");
}
if (options & MJOptionsThree) {
NSLog(@"包含了MJOptionsThree");
}
if (options & MJOptionsFour) {
NSLog(@"包含了MJOptionsFour");
}
}