美文网首页
iOS 使用 Union 存储一些状态的优缺点

iOS 使用 Union 存储一些状态的优缺点

作者: 游城十代2dai | 来源:发表于2020-04-10 21:40 被阅读0次

这个比较只是为了比较性能, 举例和实战看自己的选择

先说缺点啊哈:

代码量会多一些, 毕竟属性会自动生成 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 ? "棒极了!" : "不适合~");
}

相关文章

  • iOS 使用 Union 存储一些状态的优缺点

    这个比较只是为了比较性能, 举例和实战看自己的选择 先说缺点啊哈: 代码量会多一些, 毕竟属性会自动生成 sett...

  • MySQL有存储引擎

    MySQL有多种存储引擎,每种存储引擎有各自的优缺点,可以择优选择使用: MyISAM、InnoDB、MERGE、...

  • MySQL存储引擎

    MySQL有多种存储引擎,每种存储引擎有各自的优缺点,可以择优使用: MyISAM、InnoDB、MERGE、ME...

  • 3 MySQL存储引擎

    MySQL有多种存储引擎,每种存储引擎有各自的优缺点,可以择优选择使用: MyISAM InnoDB MERGE ...

  • MySQL存储引擎详解

    MySQL有多种存储引擎,每种存储引擎有各自的优缺点,可以择优选择使用: MyISAM、InnoDB、MERGE、...

  • 数据库问题总结

    (一)什么是存储过程?有哪些优缺点? 存储过程是一些预编译的SQL语句,简单来讲就是为以后使用而保存的一条或多条s...

  • 使用localStorage进行本地存储

    本文简单的介绍了localStorage的使用方法和优缺点,以及如何使用localStorage实现本地存储。如果...

  • swift 实现简单的 json 动画(Lottie)

    json动画优缺点 使用 1.cocoapod导入 pod 'lottie-ios', '~> 3.1.6' 2....

  • 常见的数据库基础问题

    常见的一些数据库方面的问题: (一)什么是存储过程?有哪些优缺点?存储过程是一些预编译的SQL语句。存储过程可以说...

  • IOS数据存储 之WCDB (二)WCDB.swift使用篇

    @[TOC](IOS数据存储 之WCDB (二)WCDB.swift使用篇) 上一篇:IOS数据存储 之WCDB ...

网友评论

      本文标题:iOS 使用 Union 存储一些状态的优缺点

      本文链接:https://www.haomeiwen.com/subject/ojcjmhtx.html