1

I try to call an IBOutlet, which is a property of a Singleton Object from another class but it returns nil. I´ve read a lot of of other posts about singletons here but there seems to be something that I´m missing. This is a OSX question.

In the Interface Builder I have a Button and an Object with a Singleton set as custom class. The Singletons class is called "CEOptionsST". The button is connected as IBOutlet to the Singleton´s class header.
@property (weak) IBOutlet NSButton *mybutton;

Later I´d like to access the button´s state from another class. Therefore I call:

    CEOptionsST *opt = [CEOptionsST sharedOptions];
    NSLog(@"state: %ld",(long)[[_opt mybutton] state]);

This always returns 0 no matter if the button is on or off. Using Textfields instead of buttons returns nil.

The pointer is the same when I log self from inside the Singleton´s and opt. So the Singleton is not instanced twice. When I check opt in debug mode it tells me that all properties are nil. The IBOutlet property "mybutton" is nil. So the Singleton Object initiated by the Interface Builder (or nib) is the same as opt but the state of mybutton and other properties is not accessible - what am I missing??

What I´m trying to achieve is to have UI controls as "options" for the user, which are accessible throughout the application.
Here´s my Singleton class (by Dave DeLong´s answer):

    @interface CEOptionsST : NSObject
    + (id) sharedOptions;
    @property (weak) IBOutlet NSButton *mybutton;
    @end

    @implementation CEOptionsST

    + (void)initialize{
        [self sharedOptions];
    }

    + (id)sharedOptions {
        static CEOptionsST *sharedOptions = nil;
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            sharedOptions = [[self actualAlloc] initActual];
        });
        return sharedOptions;
    }

    + (id)actualAlloc {
        return [super alloc];
    }

    + (id)alloc {
        return [CEOptionsST sharedOptions];
    }

    - (id)initActual {
        self = [super init];
        if (self) {

        }
        return self;
    }

    - (id)init {
        return self;
    }

    - (id)initWithCoder:(NSCoder *)decoder {
        return self;
    }

Thanks, Thomas

Community
  • 1
  • 1
Thomas Szabo
  • 163
  • 7

2 Answers2

1

I would strongly suggest you rethink the architecture of your app! Irrespective of that, perhaps you find your "answer" in nibs allocating instances via allocWithZone: not alloc, try overriding that to call your sharedOptions class method.

J_S
  • 560
  • 3
  • 7
  • Using allocWithZone: did not help. But I´m very open for any suggestions on how to effectively pass user interface button or textfield values to other classes that require the data. Using singleton looked like an easy solution. atm I´m reading the iboutlet values with the app delegate class and pass the values to the singleton so other classes can access them. I thought it would be easier to connect the outlets directly to the singleton. – Thomas Szabo Sep 25 '14 at 13:34
0

Your myButton object may be deallocated because only your singleton is pointing to NSButton. You should try to change reference type from weak to strong.

Another possible reason of your bug may be connected to IBOutlet and singleton. To be honest I have never seen such combination and it may not be a good practice according to Apple Guidelines. Please try to remove IBOutlet and set NSButton programically.

Szu
  • 2,254
  • 1
  • 21
  • 37