An alternative about where to register defaults


#1

Hi everyone,

I am studying chapter 13 and have been considering alternatives regarding where to place
the code for registering the defaults.

If i did this in

method of [quote]AppController.m?[/quote] would it be a good practice? instead of placing it in the suggested

??


#2

What is the particular reason for wanting to do it that way?


#3

Just wondering and seeking for alternatives…

I am totally new to Mac programming (after being in windows visual studio for years).
Trying to get things done in more than one way.

By the way, i just tried it and it works fine.
After that, i just turned back to the + (void)initialize way


#4

I hate Windows. The world would be a much better place without it. :slight_smile:

You could also create a new class named MySettings or MyDefaults or something else you choose and make it responsible for handling anything related to user defaults:

@interface MySettings: NSObject
+ (BarType)bar;
+ (void)setBar:(BarType)v;

+ (FooType)foo;
+ (void)setFoo:(FooType)v;
...

@end
@implementation MySettings

+ (void)registerDefaults {
...
}

+ (void)initialize {
   static dispatch_once_t onceToken;
   dispatch_once (&onceToken) {
      [self registerDefaults];
   }
}

+ (BarType)bar {
...
}

+ (void)setBar:(BarType)v {
...
}

+ (FooType)foo {
...
}

+ (void)setFoo:(FooType)v {
...
}

...

@end

Note how all methods are class methods.


#5

Very practical approach. Thanks a lot!!!

I still have one question:
Why do you have to make use of Grand Central Dispatch?
I am not familiar with it. I think the code you written, makes sure that:

is called only once? right?

But i thought that

is already called only once.

Thanks anyway…


#6

You don’t really have to call GCD, but I have seen cases where a class’s initialize method is begin called more than once in large programs (which I could not explain.)

Also it is worth investing time to learn GCD so that you can perform heavy computations without blocking your UI thread, and also more importantly, to make good use of the multi cores available on Macs and even on iOS devices.


#7

I have another question if you don’t mind:

You said that a solution is to create a new class e.g. a class named MySettings,
put only class methods in it and use the + (void)initialize method to register the defaults.

I did some research about + (void)initialize and i found that:

How to we cope with this possibility? That + (void)initialize may not be called,
especially if we build a special class for our job? Do we have to send a message that does nothing,
just to get the + (void)initialize method called?

In the book’s solution, AppController’s + (void)initialize is called, because AppController is used early in the application
and is instatiated early. Right?


#8

Objective-C’s run time system guarantees that a class’s +(void)initalize is called before any instances of that class are sent messages.

For example:

//
//  main.m
//

#define MY_Log() NSLog (@"%s", __PRETTY_FUNCTION__)
#define MY_Logs(P1) NSLog (@"%s: %s", __PRETTY_FUNCTION__, P1)
#define MY_LogS(P1) NSLog (@"%s: %@", __PRETTY_FUNCTION__, P1)
#define MY_Log1(P1, P2) NSLog (@"%s: "P1, __PRETTY_FUNCTION__, P2)

@interface Foo: NSObject
- (void)setupFoo;
@end

@interface Bar: NSObject
- (void)setupBar;
@end

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[])
{
    @autoreleasepool { 
        MY_Logs ("Creating a Foo...");
        Foo *foo = [[Foo alloc] init];
        [foo setupFoo];
        
        MY_Logs ("Creating a Bar..");
        Bar * __unused bar = [[Bar alloc] init];
    }
    return 0;
}

@implementation Foo

+ (void)initialize
{
    MY_Log ();
}

- (id)init
{
    MY_Log ();
    return [super init];
}

- (void)setupFoo
{
    MY_Log ();
}
@end

@implementation Bar

+ (void)initialize
{
    MY_Log ();
}

- (id)init
{
    MY_Log ();
    return [super init];
}


- (void)setupBar
{
    MY_Log ();
}
@end


#9

Here is the explanation for initialize being called twice:
http://www.mikeash.com/pyblog/friday-qa-2009-05-22-objective-c-class-loading-and-initialization.html

This would happen if there is a sub class of the original class with the initialize method, that doesn’t override this original initialize method…