App States with BOOL flags
Asked Answered
S

3

3

I've got 5 states in my app, and I use BOOL flags to mark them. But it isn't straightforward, because I have to write 5 lines to change all flags when I want to change state.

Can you write some ideas or simple code to solve this problem?

code:

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

Also, it's to bad because I can choose 2 states one time.

P.S. I found modern and more Apple-way. Answer below.

Sumac answered 21/1, 2012 at 20:22 Comment(3)
Can you post the code where you handle this at the moment please?Mowbray
It depends on how much they are mutually exclusive. If they are all indeed mutually exclusive, enum is the right choice.Ailurophile
Hm, really. It's good idea to use Sets.Sumac
P
14

Use typedef enum to define all possible states using bitmasks.

Note this will give you a maximum of up to 64 different states (on most platforms). If you need more possible states, this solution will not work.

Handling this scheme will require you to fully understand and safely handle boolean algebra.

//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
}
Pinta answered 21/1, 2012 at 20:53 Comment(5)
Wow, it's really nice, I read about it in C-book. But I need to refresh my knowledge. "1 << 3" means 00001 -> 01000? And also I can choose 2 states in one time, it's not safely, isn't it? Or it's just my problem if I don't use my flag correctly.Sumac
That depends. If you want to make sure only one state is possible at a time, never use the bitwise OR (|) but only the simple assign (=).Pinta
1 << 3 means 1 shifted three times to the left = 8.Pinta
state &= stateTwo won't remove stateTwo — it will make stateTwo the only state. If you know you have stateTwo in your bitfield, the way to remove it is state ^= stateTwo. (But note that if you don't already have stateTwo in the set, this will add it.)Hickerson
Whoopie - geee, that was stupid indeed - fixing that right away - thanks @HickersonPinta
D
1

You can always use a byte (unsigned char) size variable using its' bits as flags (each bit acts as one BOOL flag).

Good instructions to set/clear/toggle/check a bit is here.

Offcourse you'd want to set kind of human readable names for this flags, i.e.:

#define flag1 1
#define flag2 2
#define flag3 4
#define flag4 8
#define flag5 16
Design answered 21/1, 2012 at 20:31 Comment(2)
I would not recommend using defines for such job. Use an enum instead. Even better, use a typedef enum to achieve type safety.Pinta
true, but you shouldn't forget to assign the 2^x values (1,2,4,8,16...). Simple enum would assign 0,1,2,3...Design
S
-1

Nowadays we have got another option for flags. It is NS_ENUM.

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

First arg for type and second for name.

Sumac answered 6/12, 2013 at 14:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.