枚举值 它是一个整形(int) 并且,它不参与内存的占用和释放,枚举定义变量即可直接使用,不用初始化.
在代码中使用枚举的目的只有一个,那就是增加代码的可读性.
typedef enum : NSUInteger {
// 枚举成员
MTFUserManageLevelTypeNone = 0, //无状态 自身
MTFUserManageLevelTypeSeed = 1, //种子用户
MTFUserManageLevelTypeBackstage = 2, //中后台
MTFUserManageLevelTypeFinancialAdviser = 3, //理财经理
MTFUserManageLevelTypeTeamLeader = 4, //团队经理
MTFUserManageLevelTypeBusinessDepartmentLeader = 5, //营业部经理
MTFUserManageLevelTypeCityDepartmentLeader = 6 //城市部经理
} MTFUserManageLevelType; // 枚举名称
typedef NS_ENUM(NSInteger, UIViewAnimationTransition) {
UIViewAnimationTransitionNone,
UIViewAnimationTransitionFlipFromLeft,
UIViewAnimationTransitionFlipFromRight,
UIViewAnimationTransitionCurlUp,
UIViewAnimationTransitionCurlDown,
};
这是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)];
}
}