位移枚舉
目錄
- 問題引入
- 問題解析
- 概念講解
- 問題解決辦法(位移枚舉)
- 優化方法
問題引入
假定有一項考試,考試內容為辨別左、右兩個方向,辨認正確得一分.寫出考試和得分方法.
問題解析
@interface Test : NSObject
@property (nonatomic, assign) NSInteger count;
@end
@implementation Test
// 辨認方向
- (void)recognizeLeft:(BOOL)isLeft
{
if (isLeft) {
_count += 1;
}
}
- (void)recognizeRight:(BOOL)isRight
{
if (isRight) {
_count += 1;
}
}
// 得分
- (NSInteger)testGrade
{
return _count;
}
@end
上述為最直接的方法,先調用辨認方向的方法,后查看成績.
如果此時左、右代表兩大塊;左細分為左上,正左,左下;同理,右細分為右上,正右,右下.并且左上,左下, 右上,右下,辨認分值為2分.
那此時,recognizeLeft
, recognizeRight
各自變換成細分的三個方法,雖然能解決,但需要增加很多辨認方法,不是一個好的解決方式.
此時,把左(isLeft),右(isRight) 從BOOL值,轉成枚舉值,可解決上面問題.
typedef NS_ENUM (NSInteger,LeftType){
LeftTypeUnknown, // 不辨認左方向
LeftTypeTop, // 左上方
LeftTypeMiddle, // 正左方
LeftTypeBottom // 左下方
};
typedef NS_ENUM (NSInteger,RightType){
RightTypeUnknown, // 不辨認右方向
RightTypeTop, // 右上方
RightTypeMiddle, // 正右方
RightTypeBottom // 右下方
};
原來的recognizeLeft
, recognizeRight
修改:
// 辨認方向
- (void)recognizeLeft:(LeftType)leftType
{
if (leftType == LeftTypeTop) {
_count += 2;
}else if (leftType == LeftTypeMiddle) {
_count += 1;
}else if (leftType == LeftTypeBottom) {
_count += 2;
}
}
- (void)recognizeRight:(RightType)rightType
{
if (rightType == RightTypeTop) {
_count += 2;
}else if (rightType == RightTypeMiddle) {
_count += 1;
}else if (rightType == RightTypeBottom) {
_count += 2;
}
}
這樣,當辨認左上方時,若能辨認則傳LeftTypeTop
,不能則傳LeftTypeUnknown
或不調用該方法.其他各方向同理.這樣存在的問題是,雖然方法數沒增加,但是調用次數增多了.
下面,引入位移枚舉的方法講解.
概念講解
位移枚舉的定義:
typedef NS_OPTIONS (NSInteger,EnumType){
EnumTypeValue1 = 1 << 0, // 0b00000001
EnumTypeValue2 = 1 << 1, // 0b00000010
EnumTypeValue3 = 1 << 2, // 0b00000100
EnumTypeValue4 = 1 << 3 // 0b00001000
};
問題解決辦法(位移枚舉)
typedef NS_OPTIONS (NSInteger,LeftType){
LeftTypeUnknown = 1 << 0, // 不辨認左方向
LeftTypeTop = 1 << 1, // 左上方
LeftTypeMiddle = 1 << 2, // 正左方
LeftTypeBottom = 1 << 3 // 左下方
};
typedef NS_OPTIONS (NSInteger,RightType){
RightTypeUnknown = 1 << 0, // 不辨認右方向
RightTypeTop = 1 << 1, // 右上方
RightTypeMiddle = 1 << 2, // 正右方
RightTypeBottom = 1 << 3 // 右下方
};
// 辨認方向
- (void)recognizeLeft:(LeftType)leftType
{
if (leftType & LeftTypeTop) {
_count += 2;
}
if (leftType & LeftTypeMiddle) {
_count += 1;
}
if (leftType & LeftTypeBottom) {
_count += 2;
}
}
- (void)recognizeRight:(RightType)rightType
{
if (rightType & RightTypeTop) {
_count += 2;
}
if (rightType & RightTypeMiddle) {
_count += 1;
}
if (rightType & RightTypeBottom) {
_count += 2;
}
}
這樣,我們調用的時候,就可以先賦值好枚舉變量,調用辨認方法就可以了.
// 某人,左上,正左,左下,右上,右下都能辨認
- (void)test
{
LeftType leftType = LeftTypeTop | LeftTypeMiddle | LeftTypeBottom;
[self recognizeLeft:leftType];
RightType rightType = RightTypeTop | RightTypeBottom;
[self recognizeRight:rightType];
}
還是需要調用左,右兩個方法,有了位移枚舉,可以合并成一個方法.
優化方法
左、右枚舉,合并
typedef NS_OPTIONS (NSInteger,OrientationType){
OrientationTypeUnknown = 1 << 0, // 不辨認方向
OrientationTypeLeftTop = 1 << 1, // 左上方
OrientationTypeLeftMiddle = 1 << 2, // 正左方
OrientationTypeLeftBottom = 1 << 3, // 左下方
OrientationTypeRightTop = 1 << 4, // 右上方
OrientationTypeRightMiddle = 1 << 5, // 正右方
OrientationTypeRightBottom = 1 << 6 // 右下方
};
辨認方法合并
- (void)recognizeOrientation:(OrientationType)orientationType
{
if (orientationType & OrientationTypeLeftTop) {
_count += 2;
}
if (orientationType & OrientationTypeLeftMiddle) {
_count += 1;
}
if (orientationType & OrientationTypeLeftBottom) {
_count += 2;
}
if (orientationType & OrientationTypeRightTop) {
_count += 2;
}
if (orientationType & OrientationTypeRightMiddle) {
_count += 1;
}
if (orientationType & OrientationTypeRightBottom) {
_count += 2;
}
if (orientationType & OrientationTypeUnknown) {
}
}
調用方法:
// 某人,左上,正左,左下,右上,右下都能辨認
- (void)test
{
OrientationType orientationType = OrientationTypeLeftTop | OrientationTypeLeftMiddle | OrientationTypeLeftBottom | OrientationTypeRightTop | OrientationTypeRightBottom;
[self recognizeOrientation:orientationType];
}