Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simple code understanding of #define and enum

What does the code below mean?

#define kSelectedTabDefaultsKey @"Selected Tab"

 enum {
    kByName,
    kBySecretIdentity,
    };

Does #define kSelectedTabDefaultsKey @"Selected Tab" mean that we are defining a constant called "kSelectedTableTabKey" whose value is "SelectedTab"? Kind of like NSDictionary one key/value pair?

I think enum just translates kByName value = 0 and kBySecretIdentity value = 1. Is #define kSelectedTabDefaultsKey and enum tied together?

I don't think I understand it correctly because later in the code:

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

NSInteger selectedTab = [defaults integerForKey:kSelectedTabDefaultsKey];
// How does "selectedTab" get back an integer?  I thought "kSelectedTabDefaultsKey"
// was a  key with a String value of @"Selected Tab ?

UITabBarItem *item = [self.tabBar.items objectAtIndex:selectedTab];
like image 559
user1107173 Avatar asked Feb 18 '23 00:02

user1107173


2 Answers

#define kSelectedTabDefaultsKey @"Selected Tab"

This merely tells the compiler that everywhere it sees kSelectedTabDefaultsKey, it should expand it to @"Selected Tab".

So, this:

NSInteger selectedTab = [defaults integerForKey:kSelectedTabDefaultsKey];

Becomes this:

NSInteger selectedTab = [defaults integerForKey:@"Selected Tab"];

selectedTab will end up with whatever value is returned by integerForKey: after the defaults manager looks up the key @"Selected Tab" in the defaults database. Presumably, it'll be either 0 or 1 corresponding to the two values in your enum.


The enum is unrelated to the defaults key, but is a convenience.

 enum {
    kByName,
    kBySecretIdentity,
    };

This tells the compiler to substitute 0 whenever kByName is encountered and 1 for the kBySecretIdentity. No more, no less.

Thus, presumably, the value written to the database will be one of 0 or 1. The enum exists such that, in code, you can say "kByName" instead of 0, for clarity. In the code you posted, neither enum is directly mentioned because the value from the defaults database is simply passed off to select a tab.

It would be wise to check the result from the defaults database. Redefine the enum to be:

 enum {
    kByName,
    kBySecretIdentity,
    kByUnusedSentinal
    };

Then:

NSInteger selectedTab = [defaults integerForKey:kSelectedTabDefaultsKey];
if ((selectedTab < 0) || (selectedTab >= kByUnusedSentinal))
    selectedTab = kByName;

That way, if a bogon is ever written to the defaults database, your app will default to the kByName tab.

like image 97
bbum Avatar answered Feb 27 '23 09:02

bbum


#define kSelectedTabDefaultsKey @"Selected Tab" means that you are defining REPLACEMENT TEXT @"Selected Tab" (not "Selected Tab" or Selected Tab) for kSelectedTabDefaultsKey.

You could define it instead to be if (x== and it would substitute that text wherever you use the defined name (whether it makes sense or not). It's "value" is (with a few confusing exceptions) precisely the text that begins with the first non-whitespace character and ends with the end of the line (absent whitespace).

(In the languages that use begin/end instead of {/} you can create some real mischief by #defining "begin".)

like image 20
Hot Licks Avatar answered Feb 27 '23 09:02

Hot Licks