views:

115

answers:

4

I've been reading that when conforming to the NSCoding protocol and implementing the methods like -encodeWithCoder:, and encoding objects with i.e.

[coder encodeObject:self.someObject forKey:kSomeConstantToIdentifyFields];

this constant is used to keep track of that object. So later, with help of that constant, the appropriate "field" or whatever can be mapped to that object again (in this case an property).

But: Isn't this funny constant actually a random value when defined like this?

#define kSomeConstantToIdentifyFields @"fieldFooBar"

How does the system manage it to always assign the same value to that constant? Or did I get some stuff about this constants wrong? Is the value actually "fieldFooBar" and not some random number?

A: 

Do constants always keep the same value?

I believe that's why they're called constants. ;o)

baeltazor
+5  A: 

The key is a string - a name, if you will - that identifies a field in a dictionary. In this case, the dictionary is what will be written, or read from the archive that was created via the NSCoding protocol.

When you define the key like that, it's not necessarily constant, because it could be changed at some point (but only deliberately, not randomly by the system). As long as you don't change the @"fieldFooBar" string, it'll stay like that throughout the life of the program.

Keys are defined like this, not to be constant, but to be able to flag up compiler warnings and errors, such as spelling mistakes.

If you define the key once, and then refer to it by it's preprocessor symbol, if you mispell it, the compiler will throw an error saying it can't find that symbol. If you just used a string in it's place each time, then the compiler wouldn't know and wouldn't be able to warn you about it. Then you'd be on your own trying to figure out why your field isn't being decoded - because you're asking for the wrong key name.

Jasarien
Great explanation of reasons to define constants
gnarf
Very useful answer! +1
baeltazor
+2  A: 

Before your application compiles, a pre-compilation process occurs. The #define key value directive tells the pre-compiler "whenever you see key, replace it with value". It's not only that they're constants; it's as if you wrote @"fieldFooBar" all over your application yourself.

The reason not to do it yourself is to avoid mistakes, and I think Jasarien gave a great explanation for that in his answer.

Aviad Ben Dov
+2  A: 

Better way to define string constants is to use

static NSString *kSomeConstantToIdentifyFields = @"fieldFooBar";

That would same you some memory. Also, I suppose that isEqual: chects the object pointer, so having all constants point to one place is good.

Farcaller
Actually, isEqual of NSString checks the value as well...
Aviad Ben Dov
GCC merges constant NSStrings that have the same value, so there's no additional overhead to using a #define instead of a static (GCC will also do this for CFSTRs and standard C strings)
rpetrich