这个比较只是为了比较性能, 举例和实战看自己的选择
先说缺点啊哈:
代码量会多一些, 毕竟属性会自动生成 setter 和 getter
优点就是优化代码:
一个 OC 对象创建出来所占空间 16 字节的倍数, 我之前的文章有说, 那么说下极限距离, 如下面代码所示(就是随便举个例子, 实际开发就自己判定是否需要), 一个人的一些状态, 比如有 是否高, 是否富有, 是否长相英俊, 是否体重重, 是否有房等条件状态一出来, 可能就要创建五个或者更多的属性, 如代码中就有五个, 如果都用 BOOL 的属性加上一个 age 的大小, Person 类实例一创建就占用了 32 字节, 而第三层继承类 RichMan 则有 48 个字节, 可是如果不用属性而用 Union 共用体这五个属性就只有 1 个字节空间占用, 加上 age 和 isa 以及 OC 做的控件对齐, 这个 Person 实例才只有 16 字节, 第三层继承类也才 32 字节, 极大的减少了运行时需要的内存控件
PS: 做比较的时候我嫌麻烦没有注释 Union, 但是由于 Union 只有一个字节所以为了不影响测试, 写了 5 个条件, 因为多一个少一个并不影响, 要是 4 个就不是极限距离, 以下是测试代码和 log
- 使用属性的 log
32
32
48
1, 1, 1, 0, 1
这个人的相亲条件: 棒极了!
Program ended with exit code: 0
- 使用共用体的 log
16
32
32
1, 1, 1, 0, 1
这个人的相亲条件: 棒极了!
Program ended with exit code: 0
#import <Foundation/Foundation.h>
#import <malloc/malloc.h>
void _union_use(void);
int main(int argc, const char * argv[]) {
@autoreleasepool {
// insert code here...
_union_use();
}
return 0;
}
typedef enum : uint8_t {
PersonTallMask = 1 << 0,
PersonRichMask = 1 << 1,
PersonHandsomeMask = 1 << 2,
PersonHeavyMask = 1 << 3,
PersonHouseMask = 1 << 4,
} PersonMask;
@interface Person : NSObject {
@public
union {
uint8_t bits;
struct {
uint8_t tall : 1;
uint8_t rich : 1;
uint8_t handsome : 1;
uint8_t heavy : 1;
uint8_t house : 1;
};
} _personProp;
}
@property (nonatomic, assign) int age;
// 如果不用以下属性的方式创建状态, 在使用的时候 person 对象只开辟了 16 字节空间, 而用以下属性方式虽然减少了代码量, 但是内存足足开辟了 32 字节空间
// 第三层子类创建使用的时候空间也才 32 字节, 如果用了下面的属性, 就变成 48 字节了
//@property (nonatomic, assign) BOOL a;
//@property (nonatomic, assign) BOOL b;
//@property (nonatomic, assign) BOOL c;
//@property (nonatomic, assign) BOOL d;
//@property (nonatomic, assign) BOOL e;
- (BOOL)blindConditions;
- (void)setTall:(BOOL)tall;
- (BOOL)tall;
- (void)setRich:(BOOL)rich;
- (BOOL)rich;
- (void)setHandsome:(BOOL)handsome;
- (BOOL)handsome;
- (void)setHeavy:(BOOL)heavy;
- (BOOL)heavy;
- (void)setHouse:(BOOL)house;
- (BOOL)house;
@end
@implementation Person
- (BOOL)blindConditions {
return self.tall && self.rich && self.handsome && !self.heavy && self.house;
}
- (void)setTall:(BOOL)tall {
if (tall) {
_personProp.bits |= PersonTallMask;
} else {
_personProp.bits &= ~PersonTallMask;
}
}
- (BOOL)tall {
return !!(_personProp.bits & PersonTallMask);
}
- (void)setRich:(BOOL)rich {
if (rich) {
_personProp.bits |= PersonRichMask;
} else {
_personProp.bits &= ~PersonRichMask;
}
}
- (BOOL)rich {
return !!(_personProp.bits & PersonRichMask);
}
- (void)setHandsome:(BOOL)handsome {
if (handsome) {
_personProp.bits |= PersonHandsomeMask;
} else {
_personProp.bits &= ~PersonHandsomeMask;
}
}
- (BOOL)handsome {
return !!(_personProp.bits & PersonHandsomeMask);
}
- (void)setHeavy:(BOOL)heavy {
if (heavy) {
_personProp.bits |= PersonHeavyMask;
} else {
_personProp.bits &= ~PersonHeavyMask;
}
}
- (BOOL)heavy {
return !!(_personProp.bits & PersonHeavyMask);
}
- (void)setHouse:(BOOL)house {
if (house) {
_personProp.bits |= PersonHouseMask;
} else {
_personProp.bits &= ~PersonHouseMask;
}
}
- (BOOL)house {
return !!(_personProp.bits & PersonHouseMask);
}
@end
@interface Man : Person
@property (nonatomic, assign) double money;
@end
@implementation Man
@end
@interface RichMan : Man
@property (nonatomic, assign) double richMoney;
@end
@implementation RichMan
@end
/**
* 常用的状态机就可以用 Union 来节省内存的使用
*/
void _union_use(void) {
Person *per = [[Person alloc] init];
per.tall = YES;
per.rich = YES;
per.handsome = YES;
per.heavy = NO;
per.house = YES;
Man *man = [[Man alloc] init];
RichMan *richMan = [[RichMan alloc] init];
printf("%zd\n", malloc_size((__bridge const void *)(per)));
printf("%zd\n", malloc_size((__bridge const void *)(man)));
printf("%zd\n", malloc_size((__bridge const void *)(richMan)));
printf("%d, %d, %d, %d, %d\n", per.tall, per.rich, per.handsome, per.heavy, per.house);
printf("这个人的相亲条件: %s\n", per.blindConditions ? "棒极了!" : "不适合~");
}
网友评论