数据结构iOS进阶OC基础

OC-Runtime-isa

2020-07-05  本文已影响0人  xiaoyouPrince

OC - Runtime -> isa

isa 详解

15936717253401.jpg

使用位域的好处

可以节约很多内存。

比如 BOOL 类型的变量,其在内存中占用 1个字节,但是其实际使用只有 1个比特。
底层开发中可以使用比特来保存较小的数据量。一个字节可以保存8个布尔量。

这样的操作需要使用按位操作符,实际效率会更高。

自己处理bool值

缺点:各位意义不是很清晰,扩展之后更加容易增加混乱程度。

// 保存bool的变量,后三位分别为高富帅
static BOOL bools = 0b00000000;

// 掩码
#define Height_mask (1<<0)  // 最右边位 - height
#define Rich_mask (1<<1)    // 最右边二位 - rich
#define Hansom_mask (1<<2)  // 最右边三位 - hansome

#pragma mark - 取值
- (BOOL)height
{
    return !!(bools & Height_mask);
}
- (BOOL)rich{
    return !!(bools & Rich_mask);
}
- (BOOL)hansome{
    return !!(bools & Hansom_mask);
}

#pragma mark - 赋值
-(void)setHeight:(BOOL)height{
    if (height) {
        bools |= Height_mask;
    }else
    {
        bools &= ~Height_mask;
    }
}
- (void)setRich:(BOOL)rich{
    if (rich) {
        bools |= Rich_mask;
    }else
    {
        bools &= ~Rich_mask;
    }
}
- (void)setHansome:(BOOL)hansome{
    if (hansome) {
        bools |= Hansom_mask;
    }else
    {
        bools &= ~Hansom_mask;
    }
}

使用结构体内建的位域技术

直接通过位域,可以直接访问结构体内部的,但是有些东西可能就不直观了。

struct values {
        char height : 1;    // 从低到高占据的位数
        char rich: 1;
        char hansom: 1;
    } heightRichHandsom;
    
#pragma mark - 取值
- (BOOL)height
{
    return !!heightRichHandsom.height;
}
- (BOOL)rich{
    return !!heightRichHandsom.rich;
}
- (BOOL)hansome{
    return !!heightRichHandsom.hansome;
}

#pragma mark - 赋值
-(void)setHeight:(BOOL)height{
    heightRichHandsom.height = height;
}
- (void)setRich:(BOOL)rich{
    heightRichHandsom.rich = rich;
}
- (void)setHansome:(BOOL)hansome{
    heightRichHandsom.hansome = hansome;
}

共用体方式

系统方式是使用共用体,看起来更加清晰,扩展性也比较好

{
    union{
        // 真正使用的字节,
        char bits;
        
        struct {
            char height : 1;    // 具体的字节描述,更加清晰
            char rich: 1;
            char hansom: 1;
        };
    }heightRichHandsom;
}

// 掩码
#define Height_mask (1<<0)  // 最右边位 - height
#define Rich_mask (1<<1)    // 最右边二位 - rich
#define Hansom_mask (1<<2)  // 最右边三位 - hansome

#pragma mark - 取值
- (BOOL)height
{
    return !!(heightRichHandsom.bits & Height_mask);
}
- (BOOL)rich{
    return !!(heightRichHandsom.bits & Rich_mask);
}
- (BOOL)hansome{
    return !!(heightRichHandsom.bits & Hansom_mask);
}

#pragma mark - 赋值
-(void)setHeight:(BOOL)height{
    if (height) {
        heightRichHandsom.bits |= Height_mask;
    }else
    {
        heightRichHandsom.bits &= ~Height_mask;
    }
}
- (void)setRich:(BOOL)rich{
    if (rich) {
        heightRichHandsom.bits |= Rich_mask;
    }else
    {
        heightRichHandsom.bits &= ~Rich_mask;
    }
}
- (void)setHansome:(BOOL)hansome{
    if (hansome) {
        heightRichHandsom.bits |= Hansom_mask;
    }else
    {
        heightRichHandsom.bits &= ~Hansom_mask;
    }
}

枚举类型的设计

通常我们设计枚举有两种类型:可叠加不可叠加

可叠加类型
此类如设置推送消息类型的,几种类型可以相互同时设置。

typedef NS_OPTIONS(NSUInteger, UIUserNotificationType) {
    UIUserNotificationTypeNone    = 0,      
    UIUserNotificationTypeBadge   = 1 << 0, 
    UIUserNotificationTypeSound   = 1 << 1, 
    UIUserNotificationTypeAlert   = 1 << 2, 
}

// 此类可以在 set方法中通过 if 判断具体包含哪一项
if (options & UIUserNotificationTypeNone){
    // 设置的为 none 相关于关闭了
}

if (options & UIUserNotificationTypeBadge){
    // 设置的为 横幅
}

if (options & UIUserNotificationTypeSound){
    // 设置的为 声音
}

if (options & UIUserNotificationTypeAlert){
    // 设置的为 alert
}

不可叠加类型
每种类型都是独立的,无需满足既是A又是B的情况,如下:

enum {
    AUTO_HEAP_HOLES_SHRINKING       = 1,        // total size of holes is approaching zero
    AUTO_HEAP_HOLES_EXHAUSTED       = 2,        // all holes exhausted, will use hitherto unused memory in "subzone"
    AUTO_HEAP_SUBZONE_EXHAUSTED     = 3,        // will add subzone
    AUTO_HEAP_REGION_EXHAUSTED      = 4,        // no more subzones available, need to add region
    AUTO_HEAP_ARENA_EXHAUSTED       = 5,        // arena exhausted.  (64-bit only)
};

// 内部判断也是比较简单,直接 if-else 处理即可

-- end

上一篇下一篇

猜你喜欢

热点阅读