App States с флагами BOOL - PullRequest
       34

App States с флагами BOOL

3 голосов
/ 22 января 2012

В моем приложении 5 состояний, и я использую флаги BOOL, чтобы пометить их. Но это не так просто, потому что мне нужно написать 5 строк, чтобы изменить все флаги, когда я хочу изменить состояние.

Можете ли вы написать несколько идей или простой код для решения этой проблемы?

код:

//need to choose second state
flag1 = false;
flag2 = true;
flag3 = false;
flag4 = false;
flag5 = false;

Кроме того, это плохо, потому что я могу выбрать 2 состояния одновременно.

приписка Я нашел современный и более Apple-путь. Ответ ниже.

Ответы [ 3 ]

14 голосов
/ 22 января 2012

Используйте typedef enum для определения всех возможных состояний с использованием битовых масок.

Примечание это даст вам максимум до 64 различных состояний (на большинстве платформ). Если вам нужно больше возможных состояний, это решение не будет работать.

Обработка этой схемы потребует от вас полного понимания и безопасной работы с булевой алгеброй.

//define all possible states
typedef enum
{
    stateOne = 1 << 0,     // = 1
    stateTwo = 1 << 1,     // = 2
    stateThree = 1 << 2,   // = 4
    stateFour = 1 << 3,    // = 8  
    stateFive = 1 << 4     // = 16
} FiveStateMask;

//declare a state
FiveStateMask state;

//select single state
state = stateOne;         // = 1

//select a mixture of two states
state = stateTwo | stateFive;     // 16 | 2 = 18

//add a state 
state |= stateOne;                // 18 | 1 = 19

//remove stateTwo from our state (if set)
if ((state & stateTwo) == stateTwo)
{
    state ^= stateTwo;           // 19 ^ 2 = 17
}

//check for a single state (while others might also be selected)
if ((state & stateOne) == stateOne)
{
    //stateOne is selected, do something
}

//check for a combination of states (while others might also be selected)
if ((state & (stateOne | stateTwo)) == stateOne | stateTwo)
{
    //stateOne and stateTwo are selected, do something
}

//the previous check is a lot nicer to read when using a mask (again)
FiveStateMask checkMask = stateOne | stateTwo;
if ((state & checkMask) == checkMask)
{
    //stateOne and stateTwo are selected, do something
}
1 голос
/ 22 января 2012

Вы всегда можете использовать переменную размера байта (без знака), используя ее биты в качестве флагов (каждый бит действует как один флаг BOOL).

Хорошие инструкции для установки / сброса / переключения / проверки бита: здесь .

Конечно, вы бы хотели установить для этого типа флагов удобочитаемые имена, например:

#define flag1 1
#define flag2 2
#define flag3 4
#define flag4 8
#define flag5 16
0 голосов
/ 06 декабря 2013

В настоящее время у нас есть еще одна опция для флагов. Это NS_ENUM .

typedef NS_ENUM(NSInteger, UITableViewCellStyle) {
    UITableViewCellStyleDefault,
    UITableViewCellStyleValue1,
    UITableViewCellStyleValue2,
    UITableViewCellStyleSubtitle
};

Первый аргумент для типа и второй для имени.

...