-2

I have been looking around for solutions on how to create a singleton pattern which is thread safe on ios. I came upon basically the same solutions over and over but when I init the object the pointer still says null. As you can tell from the screenshot.

It's pretty strange since nobody on the internet seems to have had this issue so far. I myself need to compare if the sharedInstance is initialized to enter a certain piece of code somewhere else and it will always tell me after init that it is nil.

What's this about? Anybody any clues? I want to understand! :D

Thanks in advance, cheers, Thor

// Why this is not a duplicate: // This question is not about the proper init it is about why the sharedInstance is not behaving like it should after. I still got the problem of not being able to compare it to nil or even have a comparison in the sharedInstance method to prevent from overwriting the singleton. How to prevent from overwriting would be my followup question? I even tried it with another BOOL which I set to true during the init. The result is, the if (!bool) will be seen as true although my debugger says bool==yes-> !bool should be false.

THE QUESTION: Why is my pointer to the instance returned properly and outside (on the caller methods side) results to nil? To make it clear a call from outside:

ControlSchemes *cs = [ControlSchemes sharedInstance];

will enter the code of sharedInstance have a valid pointer to a valid object in the return according to the debugger BUT will then have nil inside the cs after stepping over. Why?

//

enter image description here

Thor
  • 29
  • 6

3 Answers3

3

You should create your singletons this way.

+ (instancetype)sharedInstance
{
    static dispatch_once_t once;
    static id sharedInstance;
    dispatch_once(&once, ^{
        sharedInstance = [[self alloc] init];
    });
    return sharedInstance;
}
Jaeger
  • 324
  • 1
  • 10
1

In addition to Jaeger's answer which shows the recommended way to create a singleton, here's why you have a complete failure:

You are calling [super allocWithZone]. You are calling this in a class method. Inside a class method, self is a class. Not an instance, but a class. super is therefore not the superclass of your class (like the superclass of ControlSchemes), but the superclass of Class. But Class has no superclass. It's superclass is Nil. So you send allocWithZone to nil, and get nil back.

Even if you called alloc for the superclass of ControlSchemes, that would be obviously nonsense, because you don't want an instance of the superclass, but an instance of ControlSchemes.

gnasher729
  • 51,477
  • 5
  • 75
  • 98
  • Thanks ... that's a good hint... but as seen with Jaegers approach (first screenshot [self alloc]) I will still get the pointer valid to the return statement but the returned pointer in the callers method is nil. Any clues on this? – Thor Jul 15 '15 at 08:17
0

Okay after the adjustments I made with Jaegers help I figured out that I used a second variable as seen in the first screenshot.

So I assume:

The problem with my first implementation (-> see screenshot 2) is answered by gnasher729.

The problem with the second implementation with adjustments from Jaeger (-> see screenshot 1) is a simple double initialization of sharedInstance(out of the ifs scope for the return)

Thanks guys

Thor
  • 29
  • 6