1. 位移枚举的用法
// - 定义 NSLayoutAttributeLeft NSLayoutAttributeRight 是系统定义,分别为 1, 2, 3, 这个写法很秀...大家注意
typedef NS_OPTIONS(NSInteger, MASAttribute) {
MASAttributeLeft = 1 << NSLayoutAttributeLeft,
MASAttributeRight = 1 << NSLayoutAttributeRight,
MASAttributeTop = 1 << NSLayoutAttributeTop,
}
// - 使用 1. 适合 同时存在 MASAttributeLeft | MASAttributeRight | MASAttributeTop
if (attrs & MASAttributeLeft) [attributes addObject:self.view.mas_left];
if (attrs & MASAttributeRight) [attributes addObject:self.view.mas_right];
if (attrs & MASAttributeTop) [attributes addObject:self.view.mas_top];
//- 使用 2. 适合只存在 MASAttributeLeft 或者 MASAttributeRight 或者 MASAttributeTop 中的某一种情况
switch (attrs & 0xFF) {
case MASAttributeLeft:
break;
case MASAttributeRight:
break;
case MASAttributeTop:
break;
default:
break;
}
2. 枚举赋值
/** 表示两个 BOOL 值 */
typedef NS_OPTIONS(NSInteger, DYRoomStateType) {
DYRoomStateTypeUnknow = 0,
DYRoomStateTypeFirstConnect = 1 << 1,
DYRoomStateTypeFirstEnterRoom = 1 << 2,
DYRoomStateTypeFirstQuitRoom = 1 << 3,
DYRoomStateTypeFirstTestRoom = 1 << 4,
};
static inline void setCurrentTypeToTypeStaute(NSInteger* currentType, NSInteger toType, BOOL status){
// - 加入这个type 已知当前是 1001 , 加入的是 0010, 结果是1011;
if (status) {
(*currentType) = (*currentType) | (toType);
}else{
// - 移除这个type 已知当前是 1011 , 移除的是 0010, 结果是1001;
(*currentType) = (*currentType) & (~toType);
}
}
// - 获取是不是包含这个 type 已知当前是 1011 , 测试的是 0010, 结果是0010;
static inline BOOL getCurrentTypeIsType(NSInteger* currentType, NSInteger isType){
return ((*currentType) & isType) == isType;
}
2. 枚举位运算的新写法(一个枚举值标表示三个字段 每个字段有 YES 和 NO 两个状态) 这里的!! 是 int 类型转成 BOOL类型的思路不错
// - 使用位运算赋值
typedef NS_OPTIONS(NSInteger, QGMask) {
QGMaskHandsome = 1 << 0,
QGMaskRich = 1 << 1,
QGMaskTall = 1 << 2,
}
@interface MJPerson : NSObject
- (void)setTall:(BOOL)tall;
- (void)setRich:(BOOL)rich;
- (void)setHandsome:(BOOL)handsome;
- (BOOL)isTall;
- (BOOL)isRich;
- (BOOL)isHandsome;
@interface MJPerson(){
char _tallRichHandsome;
}
@end
@implementation MJPerson
- (instancetype)init{
self = [super init];
if (self) {
_tallRichHandsome = 0b00000000;
}
return self;
}
- (void)setTall:(BOOL)tall{
if(tall){
_tallRichHandsome |= QGMaskTall;
}else{
_tallRichHandsome &= ~QGMaskTall;
}
}
- (BOOL)isTall{
return !!(_tallRichHandsome & QGMaskTall) ;
}
- (void)setRich:(BOOL)rich{
if(rich){
_tallRichHandsome |= QGMaskRich;
}else{
_tallRichHandsome &= ~QGMaskRich;
}
}
- (BOOL)isRich{
return !!(_tallRichHandsome & QGMaskRich) ;
}
- (void)setHandsome:(BOOL)handsome{
if(handsome){
_tallRichHandsome |= QGMaskHandsome;
}else{
_tallRichHandsome &= ~QGMaskHandsome;
}
}
- (BOOL)isHandsome{
return !!(_tallRichHandsome & QGMaskHandsome) ;
}
3. 结构体+位域 (使用结构体+位域重新实现上述的功能)
@interface MJPerson : NSObject
struct {
char tall : 2;
char rich : 2;
char handsome : 2;
}_tallRichHandsome;
@end
@implementation MJPerson
- (void)setTall:(BOOL)tall
{
_tallRichHandsome.tall = tall;
}
- (void)setRich:(BOOL)rich
{
_tallRichHandsome.rich = rich;
}
- (void)setHandsome:(BOOL)handsome
{
_tallRichHandsome.handsome = handsome;
}
- (BOOL)tall
{
return _tallRichHandsome.tall;
}
- (BOOL)rich
{
return _tallRichHandsome.rich;
}
- (BOOL)handsome
{
return _tallRichHandsome.handsome;
}
@end
4. 共用体+位域 (使用共用体+位域重新实现上述的功能)
#define TallMask (1<<2) // 0b00000100 4
#define RichMask (1<<1) // 0b00000010 2
#define HandsomeMask (1<<0) // 0b00000001 1
@interface Person()
{
union {
char bits;
// 结构体仅仅是为了增强代码可读性,无实质用处 只是用来标识 bits中的后三位对应着的内容表示的是什么
struct {
char tall : 2;
char rich : 2;
char handsome : 2;
};
}_tallRichHandsome;
}
@end
@implementation Person
- (void)setTall:(BOOL)tall{
// - 下边两个方法的写法都可以, 第一个可以增强可读性, 第二个提高效率
// - _tallRichHandsome.tall = tall;
if (tall) {
_tallRichHandsome.bits |= TallMask;
}else{
_tallRichHandsome.bits &= ~TallMask;
}
}
- (void)setRich:(BOOL)rich{
if (rich) {
_tallRichHandsome.bits |= RichMask;
}else{
_tallRichHandsome.bits &= ~RichMask;
}
}
- (void)setHandsome:(BOOL)handsome{
if (handsome) {
_tallRichHandsome.bits |= HandsomeMask;
}else{
_tallRichHandsome.bits &= ~HandsomeMask;
}
}
- (BOOL)tall{
// - 下边两个方法的写法都可以, 第一个可以增强可读性, 第二个提高效率
// - return _tallRichHandsome.tall;
return !!(_tallRichHandsome.bits & TallMask);
}
- (BOOL)rich{
return !!(_tallRichHandsome.bits & RichMask);
}
- (BOOL)handsome{
return !!(_tallRichHandsome.bits & HandsomeMask);
}
5. 枚举的新写法 (用枚举标示数组下标和数组长度)
/** 连麦的人物的角色 */
typedef NS_ENUM(NSUInteger, QIEOnlineMatchPeopleRole) {
QIEOnlineMatchPeopleRoleHost = 0, /**< 连麦时候不显示画面的 */
QIEOnlineMatchPeopleRoleConvener = 1, /**< 连麦时候需要显示画面的 */
QIEOnlineMatchUsersArrayLenght = 2, /**< 用户数组的长度 */
};
/** 用户数组 0 : 主播数组, 1: 选手数组 */
- (NSMutableArray<NSMutableArray *> *)usersArray{
if(!_usersArray){
_usersArray = [NSMutableArray array];
NSMutableArray <AgoraLiveTranscodingUser *> *hostArray = [NSMutableArray array];
NSMutableArray <AgoraLiveTranscodingUser *> *guestArray = [NSMutableArray array];
[_usersArray addObject:hostArray];
[_usersArray addObject:guestArray];
}
return _usersArray;
}
// - 根据枚举取出对应下标的元素
[[self.usersArray objectAtIndex:QIEOnlineMatchPeopleRoleHost] addObject:user];
[[self.usersArray objectAtIndex:QIEOnlineMatchPeopleRoleConvener] addObject:user];
[[self.usersArray objectAtIndex:QIEOnlineMatchPeopleRoleConvener] addObject:user];
// - 根据枚举 判断数组长度是不是达到了最大值
if(self.usersArray.count == QIEOnlineMatchUsersArrayLenght){
NSLog(@"数组长度已经达到最大值");
}
5. 枚举的新写法 (用一个枚举值标示两个字段, 每个字段有多个状态)
/** 推流器的枚举
第一个低八表示 pk 模式 (个人赛和线上赛)
第二个低八位标示 推流方式(声网推流或者斗鱼推流)
*/
typedef NS_ENUM(NSInteger, QIEPushFlowType) {
/** 使用用于个人连麦或者线上赛 */
QIEPushFlowTypeForMask = 0x00FF,
QIEPushFlowForOnlineMatch = 1,
QIEPushFlowForPersonal = 2,
QIEPushFlowTypeForSet = (QIEPushFlowForOnlineMatch | QIEPushFlowForPersonal),
/** 使用斗鱼的推流器或者声网推流器 */
QIEPushFlowTypeByMask = 0xFF00,
QIEPushFlowByDy = 256,
QIEPushFlowByAgora = 512,
QIEPushFlowTypeBySet = (QIEPushFlowByDy | QIEPushFlowByAgora)
};
// - setter 方法
- (void)setPushFlowType:(QIEPushFlowType)pushFlowType{
// - 验证参数合法性
NSAssert((pushFlowType & QIEPushFlowTypeForMask) != QIEPushFlowTypeForSet), @"QIEPushFlowFor之间不能做位运算...");
NSAssert((pushFlowType & QIEPushFlowTypeByMask) != QIEPushFlowTypeBySet, @"QIEPushFlowBy之间不能做位运算...");
// - 赋值
if((pushFlowType & QIEPushFlowTypeForMask) & QIEPushFlowTypeForSet){
// - 说明 QIEPushFlowTypeFor 是 QIEPushFlowTypeForSet 的其中之一,也就是说 第一低八位不是 0
_pushFlowType = (pushFlowType & QIEPushFlowTypeForMask) + (_pushFlowType & QIEPushFlowTypeByMask);
}
if((pushFlowType & QIEPushFlowTypeByMask) & QIEPushFlowTypeBySet){
// - 说明 QIEPushFlowTypeBy 是 QIEPushFlowTypeBySet 的其中之一,也就是说 第二低八位不是 0
_pushFlowType = (_pushFlowType & QIEPushFlowTypeForMask) + (pushFlowType & QIEPushFlowTypeByMask);
}
}
NSTest *t = [[NSTest alloc]init];
// - 会崩溃, 停在断言的位置
t.pushFlowType = QIEPushFlowForPersonal | QIEPushFlowForOnlineMatch; 和 t.pushFlowType = QIEPushFlowByDy | QIEPushFlowByAgora;
// - 可以记录值 QIEPushFlowByAgora 和 QIEPushFlowForOnlineMatch
t.pushFlowType =QIEPushFlowByAgora | QIEPushFlowForOnlineMatch;
// - 切换不会使原有的值丢失 (QIEPushFlowForOnlineMatch 还会保留)
t.pushFlowType =QIEPushFlowByDy