views:

46

answers:

1

Hey all.

I initialized a class in my singleton called DataModel. Now, from my UIViewController, when I click a button, I have a method that is trying to access that class so that I may add an object to one of its dictionaries. My get/set method passes back the pointer to the class from my singleton, but when I am back in my UIViewController, the class passed back doesn't respond to methods. It's like it's just not there. I think it has something to do with the difference in passing pointers around classes or something. I even tried using the copy method to throw a copy back, but no luck.

UIViewController:

ApplicationSingleton *applicationSingleton = [[ApplicationSingleton alloc] init];

DataModel *dataModel = [applicationSingleton getDataModel];

[dataModel retrieveDataCategory:dataCategory];

Singleton:

ApplicationSingleton *m_instance;
DataModel *m_dataModel;

- (id) init {
    NSLog(@"ApplicationSingleton.m initialized.");
    self = [super init];
    if(self != nil) {
        if(m_instance != nil) {
            return m_instance;
            }
        NSLog(@"Initializing the application singleton.");
        m_instance = self;
        m_dataModel = [[DataModel alloc] init];   
        }
    NSLog(@"ApplicationSingleton init method returning.");
    return m_instance;
    }

-(DataModel *)getDataModel {
    DataModel *dataModel_COPY = [m_dataModel copy];
    return dataModel_COPY;
    }

For the getDataModel method, I also tried this:

-(DataModel *)getDataModel {
    return m_dataModel;
    }

In my DataModel retrieveDataCategory method, I couldn't get anything to work. I even just tried putting a NSLog in there but it never would come onto the console.

Any ideas?

+1  A: 

Most likely you are sending messages that get ignored, e.g. they're being sent to objects which don't exist/aren't the one you're looking for, and for some reason aren't crashing. This occurs in the case of messaging nil, or possibly other illegitimate values. Although you seem to expect that the m_ variables will be initialized to 0, this is not good form, and furthermore you are not following a very typical objc pattern for your singletons -- m_dataModel should be an ivar of m_instance, and m_instance should probably be declared static, as you probably don't want it accessed from other files directly. In addition, the most likely source of your bug is somehow the -init method, which should never be called on a singleton -- instead do something like this:

+ (ApplicationSingleton *)sharedInstance {
     static ApplicationSingleton *instance = nil;
     if(!instance) {
          instance = [[self alloc] init]; //or whatever custom initializer you would like, furthermore some people just put the initialization code here and leave -init empty
     }
     return instance;
}

the code you have now leaks because you allocate an object (self) and don't release it before returning a potentially different instance (the shared one if one already exists), such that the newly allocated one is typically lost.

Jared P
It is guaranteed that instance variables will be initialized to 0. It's perfectly good form to assume things that are part of the language, much like we assume 1 + 3 will be 4.
Chuck
My wording was poor -- I meant to express that it is not particularly clear, and thus a bad practice in general, though not technically wrong. Furthermore, because the variable is not declared static, if elsewhere in the code (presumably in a different file, at file scope) if there was another declaration of the variable(s) WITH a static initializer, then the variables would not be 0, (obvi they'd be whatever they were initialized to elsewhere in code). While this is unlikely to happen, its more of a best practices thing, like making singleton ivars actual ivars, and not just static vars.
Jared P
@Chuck: Those don't look like ivars to me, they seem to be in the implementation file. @Jared: If its not clear to someone that ivars are initialized to 0, that person should go back to read about the basics of the language :)
Georg Fritzsche
@Georg: Good point. I assumed the variables were actually in the interface and it was just elided (since `m_` is usually an ivar prefix), but that might not be justified.
Chuck
@Georg if someone notes that the 'ivars' were actually static vars, and then went on to say that ivars are initialized to zero when what was in fact discussed was that the actually-static-vars-and-not-ivars would not be initialized to zero, that person should go back and read about the basics of language.
Jared P
Er, you didn't make a distinction between ivars and non-ivars in that comment above. As it is it reads as if you find relying on zero-initializing of ivars bad practice too. So much for language-basics ;)
Georg Fritzsche