iOS枚举用法介绍 enum,NS_ENUM,NS_OPTIONS

前言

枚举 它是一个整形(int)  并且,它不参与内存的占用和释放,枚举定义变量即可直接使用,不用初始化.

在代码中使用枚举的目的只有一个,那就是增加代码的可读性.


enum使用

typedef enum : NSUInteger {
    // 枚举成员
    MTFUserManageLevelTypeNone = 0,  //无状态  自身
    MTFUserManageLevelTypeSeed = 1,  //种子用户
    MTFUserManageLevelTypeBackstage = 2,  //中后台
    MTFUserManageLevelTypeFinancialAdviser = 3, //理财经理
    MTFUserManageLevelTypeTeamLeader = 4,    //团队经理
    MTFUserManageLevelTypeBusinessDepartmentLeader = 5,  //营业部经理
    MTFUserManageLevelTypeCityDepartmentLeader = 6     //城市部经理
    
} MTFUserManageLevelType; // 枚举名称


NS_ENUM (推荐 结构非常清晰)

typedef NS_ENUM(NSInteger, UIViewAnimationTransition) {
    UIViewAnimationTransitionNone,
    UIViewAnimationTransitionFlipFromLeft,
    UIViewAnimationTransitionFlipFromRight,
    UIViewAnimationTransitionCurlUp,
    UIViewAnimationTransitionCurlDown,
};


NS_OPTIONS (位运算枚举)

这是Apple文档里面的

typedef NS_OPTIONS(NSUInteger, UIViewAutoresizing) {
    UIViewAutoresizingNone                 = 0,
    UIViewAutoresizingFlexibleLeftMargin   = 1 << 0,
    UIViewAutoresizingFlexibleWidth        = 1 << 1,
    UIViewAutoresizingFlexibleRightMargin  = 1 << 2,
    UIViewAutoresizingFlexibleTopMargin    = 1 << 3,
    UIViewAutoresizingFlexibleHeight       = 1 << 4,
    UIViewAutoresizingFlexibleBottomMargin = 1 << 5
};

什么时候要用到这种方式呢?

那就是一个枚举变量可能要代表多个枚举值的时候. 其实给一个枚举变量赋予多个枚举值的时候,原理只是把各个枚举值加起来罢了. 例如很多第三方库里面  YYKit SDWebImage  和 AF里面都有类似的枚举

当加起来以后,就获取了一个新的值,那么为了保证这个值的唯一性,这个时候就体现了位运算的重要作用.

位运算可以确保枚举值组合的唯一性.

因为位运算的计算方式是将二进制转换成十进制,也就是说,枚举值里面存取的是 计算后的十进制值.

打个比方:

通过上面的位运算方式设定好枚举以后,打印出来的枚举值分别是: 1 2 4 8 

这4个数字,无论你如何组合在一起,也不会产生两个同样的数字.

不过Apple也提供给我们方便的创建方式 unit

typedef NS_ENUM(uint, Test)  
{  
    TestA,  
    TestB,  
    TestC,  
    TestD
};  

我们还是自己手动创建 自己写位运算就好了,这也是最常见的做法

typedef NS_OPTIONS(NSUInteger, _Name){
    NameA = 1 << 0, // 1   0000 0001
    NameB = 1 << 1, // 2   0000 0010
    NameC = 1 << 2, // 4   0000 0100
    NameD = 1 << 3  // 8   0000 1000
};

这个稍微理解下就很简单,主要是对几个运算符  & | ^的理解

NSLog(@"%ld,%ld,%ld,%ld",NameA,NameB,NameC,NameD); // 位运算的枚举值相加之和
    // 2018-04-11 09:38:34.132034+0800 enum[1531:51025] 1,2,4,8
    
    
    _Name name = (NameA | NameB); // 和
    NSLog(@"%ld",name); // 3
    
    // & 符号是判断枚举是否保存后面的枚举类型  (NameA | NameB) & NameA
    // 2018-04-11 09:38:34.132246+0800 enum[1531:51025] 存在NameA
    if (name & NameA) {
        NSLog(@"存在NameA");
    }
    else{
        NSLog(@"不存在NameA");
    }
    
    // (NameA | NameB) & NameC
    // 2018-04-11 09:38:34.132332+0800 enum[1531:51025] 不存在NameC
    if (name & NameC) {
        NSLog(@"存在NameC");
    }
    else{
        NSLog(@"不存在NameC");
    }
    
    // | 符号是给已有的枚举添加新的类型
    // (NameA | NameB)   --- >  (NameA | NameB | NameC)
    name |= NameC;
    
    // (NameA | NameB | NameC) & NameC
    // 2018-04-11 09:38:34.132430+0800 enum[1531:51025] 存在NameC
    if (name & NameC) {
        NSLog(@"存在NameC");
    }
    else{
        NSLog(@"不存在NameC");
    }
    
    // ^ 是剔除某个枚举
    // (NameA | NameB | NameC) --> (NameB | NameC)
    name ^= NameA;
    // (NameB | NameC) & NameA
    // 2018-04-11 09:38:34.132516+0800 enum[1531:51025] 不存在NameA
    if (name & NameA) {
        NSLog(@"存在NameA");
    }
    else{
        NSLog(@"不存在NameA");
    }
    // 注意,当^的时候,如果整个类型是没有的,那么^的意思和|是一样的
    name ^= NameD;
    NSLog(@"%ld",name); // 14


可以看出如果你用 | 运算符多个枚举类型,就是代表多个类型,可以理解为"加法"

你用 & 运算符一个类型的枚举,代表包含关系 就类似上面的左边元素是否包含右右边元素 

你用 ^ 运算符对应的就是 | 运算符,意思是剔除的意思 有的话就剔除,但是如果没有的话^就是等于|,会把元素加进去


非常清晰,记录一下,根据需求推荐用后面两种




// 以下是缓存计算的一个东西  可以忽略

/*

 一般情况下这个计算Size的方法都安排在异步线程中的,所以需要用performSelector的方法回到主线程中刷新UI

 */



// 文件操作单粒

NSFileManger *fileManager = [NSFileManager defaultManager];



// 获取文件缓存路径

NSString *cachePath = [NSSearchPathForDirectoriesDomains(NSCachesDirectory,NSUserDomainMask,YES) ObjectAtIndex:0];



// 返回所有的文件名字

NSArray *files = [fileManager subpathsAtPath:cachepath];



// 总大小

long long fileSize = 0;



// 便利内部所有文件名字,然后和主Cache拼接在一起

for (NSString *p in files)

{

    // 拼接完整的路径

    NSString *path = [cachepath stringByAppendingPathComponent:p];



    if ([fileManager fileExistsAtPath:path])

    {

        // 根据绝对路径拼接出来的东西算出一个字典,内部有个FileSize拿出文件大小

        fileSize += [fileManager attributesOfItemAtPath:path error:nil].fileSize

    }



    // NSString+CP的catagory有一个方法把文件大小转换成KB

    self.cacheFileSize = [NSString stringWithFormat:@"%@",[NSString stringWithFile:fileSize]];



        // 回到主线程刷新UI  waitUntile  YES那么就是等线程结束的时候再进行方法,No的话就直接返回到主线程去刷新UI,不等子线程做完,如果当前线程是在主线程的话那么YES也就和NO一样直接返回到主线程刷新UI

        [self performSelectorOnMainThread:@selector(updateFileSizeLabel:) withObject:@(fileSize)waitUntil:YES];

}





// 给对应的cell增加fileSize的大小

- (void)updateFileSizeLabel:(NSNumber *)date{

    // 获取多少KB

    NSString *fileSize = [NSString stringWithFormat:@"%@",[NSString stringWithFileSize:date doubleValue]];

    // 通过settingsReader根据Key拿到indexpath

    NSIndexPath *indexPath = [self.settingReader indexPathForKey:@"ClearCache"];

    UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexpath];

    cell.detailTextLabel.text = fileSize;

    [cell.detailTextLabel setNeedsDisplay];

}





// 给NSString加的一个Category 用来计算fileSize的显示大小

+ (NSString*)stringWithFileSize:(unsigned long long)size

{

    if (size == 0)

    {

        return @"无缓存";

    }

    else if (size < 1000)

    {

        return [NSString stringWithFormat:@"%lluB", size];

    }

    else if(size < 1024 * 1024)

    {

        return [NSString stringWithFormat:@"%.2fKB", size / 1024.0];

    }

    else if(size < 1024 * 1024 * 1024)

    {

        return [NSString stringWithFormat:@"%.2fMB", size / (1024.0 * 1024)];

    }

    else if(size < 1024 * 1024 * 1024 * 1024ull)

    {

        return [NSString stringWithFormat:@"%.2fGB", size / (1024.0 * 1024 * 1024)];

    }

    else

    {

        return [NSString stringWithFormat:@"%.2fTB", size / (1024.0 * 1024 * 1024 * 1024)];

    }

}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值