2012-01-21 3 views
3

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

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

код:

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

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

P.S. Я нашел современный и более Apple-way. Ответ ниже.

+0

Можете ли вы разместить код, на котором вы сейчас справитесь, пожалуйста? –

+1

Это зависит от того, насколько они являются взаимоисключающими. Если все они действительно взаимоисключающие, «перечисление» является правильным выбором. – Costique

+0

Хм, действительно. Рекомендуется использовать Sets. – kaspartus

ответ

14

Используйте 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 
} 
+0

Ничего себе, это действительно хорошо, я читал об этом в C-книге. Но мне нужно освежить свои знания. «1 << 3» означает 00001 -> 01000? А также я могу выбрать 2 состояния за один раз, это не безопасно, не так ли? Или это просто моя проблема, если я не правильно использую свой флаг. – kaspartus

+0

Это зависит от меня. Если вы хотите, чтобы за один раз было возможно только одно состояние, никогда не используйте побитовое ИЛИ (|), а только простое назначение (=). – Till

+0

1 << 3 означает 1 сдвинутый три раза влево = 8. – Till

1

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

Хорошие инструкции по установке/очистке/переключению/проверке бит here.

Offcourse вы хотите установить тип считываемых имен человека для этого флагов, т.е .:

#define flag1 1 
#define flag2 2 
#define flag3 4 
#define flag4 8 
#define flag5 16 
+1

Я бы не рекомендовал использовать определения для такого задания. Вместо этого используйте перечисление. Еще лучше, используйте typedef enum для обеспечения безопасности типов. – Till

+0

true, но вы не должны забывать назначать значения 2^x (1,2,4,8,16 ...). Простой enum присваивал бы 0,1,2,3 ... –

-1

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

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

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