Got the challenge with similar code to the provided solution. I should have thought to move the

[colorWell setColor:[PreferenceController preferenceTableBgColor]]; [checkbox setState:[PreferenceController preferenceEmptyDoc]];
into a separate routine as shown in the solution, since the exact same code is used earlier. That was un-SMRT of me. I’m not sure I get the advantage of setting up the array and fast enumerating through the keys, though. Seems like a simple

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; [defaults removeObjectForKey:BNRTableBgColorKey]; [defaults removeObjectForKey:BNREmptyDocKey];
would be more efficient, since you’re not re-fetching the shared defaults object repeatedly, and you don’t have the overhead of creating and traversing the array. But maybe this is negligible. Since you have to list all of the keys when you build the NSArray anyway, I’m just not seeing the payback. Is it for a more complicated set of preferences? Enquiring minds (well, mine anyway) want to know! :geek:


you aren’t creating or traversing anything?

ObjectiveC is about objects:

sharedUserDefaults is an object which in itself is a collection of objects. All you are doing is changing pointers to point to various area’s of that objects, you aren’t fetching results at all. Remember even a string (NSString) is treated as an object, which has a memory allocation, with a pointer pointing to it.

NSString *helloWorld = @“lolCats”;
NSString *anotherWorld = helloWorld;

All that does is make anotherWorld have the SAME memory location as helloWorld. The way I think you saw it was in this light:

NSString *hellowWorld = @“lolCats”;
NSString *anotherWorld = [NSString stringWithString:helloWorld];
//or alternatively that is the same as doing:
// NSString *anotherWorld = @“lolCats”

The first example is pointing a pointer to an already existing location, the second is creating a string FROM a pointer location i.e. duplication, which in effect is the same as manually creating it as in the commented code.

This is what makes OC so efficient, it’s a bunch of pointers repointing to reduce redundancy in data, as well as unnecessary calls to and from various functions to populate, ‘traverse’ and otherwise copy or manipulate.

An analogy I would use is:

  1. You call someone on your mobile
  2. You need to call another person too from that mobile

what do you do? Get another mobile to call someone? or simply switch pointer (put the call on call holding) and make another call?


Sorry again to bother with an old topic on an old book edition. After having going through the 2nd edition of the book in the past month (and managed to adapt the exercises to recent changes in Cocoa, Xcode and OBJ-C), I started with the 4th edition to get a bit more updated… Next month I should have filled the gap in my knowledge and start with the 6th edition of the book.

For this challenge I’ve created this solution, which works fine, but I am not quite sure it’s the best and most elegant one:

- (void)resetDefaults:(id)sender {
    [[NSUserDefaults standardUserDefaults] removeObjectForKey:BNRTableBgColorKey];
    [[NSUserDefaults standardUserDefaults] removeObjectForKey:BNREmptyDocKey];
    [PreferenceController initialize];
    [_colorWell setColor:[PreferenceController preferenceTableBgColor]];
    [_checkBox setState:[PreferenceController preferenceEmptyDoc]];

This is the IBAction method the reset to defaults button in the preference panel is connected to.
In particular I’m not sure if calling the +initialize class method again on the PreferenceController it’s ok, or if it would be better to just create a similar class method in the PreferenceController class which does exactly the same +initilaize does.

PS Perhaps using bindings on those two UI elements in the NIB might as well avoid to reset them programmatically in the method and spare two lines of code? I’m thinking about the situation when a preference panel for an app has much more than just two options represented in the UI, so in that case using bindings would be a saver from glue code.

Thanks for any given feedback.