This is a very simple idea, and one that’s useful for settings. You might have a settings screen, and your actual little game and they need to read from (the game) and write to (the settings screen) from an object they can both access.
This simple concept took a lot of googling to find out for someone who is wholly new to Obj-C coming from more of a Actionscript 3.0 background.
Lets look at the implimentation or .m file first strangely enough
#import "Global.h" @implementation Global static Global *_instance = nil; // <-- important +(Global *)instance { // skip everything if(_instance) return _instance; // Singleton @synchronized([Global class]) <-- important, honestly not sure what synchronized is yet, im learning as i go along too - but its very important! { if(!_instance) { _instance = [[self alloc] init]; // NSLog(@"Creating global instance!"); <-- You should see this once only in your program } return _instance; } return nil; } @synthesize _difficulty, _useAccelerometer; @end
—
Firstly we create the variable,
*_instance(the * means pointer) of the type Global. the qualifier ‘static’ hear means the it’s a class variable, meaning instances cannot access it.
Note that global itself, that you’ll be using will be an instance of the Global class. What that means is that, everything else we’ll be doing we do it as if we would a regular class, which is great!
I had tried to find a way previously on how to write and store static variables, and it was actually really convoluted and i had to write 7 lines of code for each variable, basically creating setters for them manually. It was a pain, but I thought wellp, thats how it’s done…fine.
Alright, the next thing to note, is the
if(_instance) return _instance;
call happens early in the ‘+instance’ funciton, before the syncrhonization which will save us some cycles if we’re using it in runtime loops with arrays. Coming from a flash background, one good thing is that you realize how every little bit counts. And since our games we all will make, will be pretty awesome we need those cycles for our sweet graf-x.
Now lets take a look at the header or .h file
#import <Foundation/Foundation.h> <-- important @interface Global : NSObject { int _difficulty; // [Edit] - '0' typo removed - Thanks Greg BOOL _useAccelerometer; }; @property(nonatomic) int _diffculty; @property(nonatomic) BOOL _useAccelerometer; // methods + (Global *)instance; // <-- important, notice the +
So here we import the Foundation class, so that we can extend NSObject, the most basic usable object that exist in objective-c.
Note the
+(Global *)instance;
line.
We have class (not instance of class) method called “instance” (sans underscore) – which acts like a getter for our ‘_instance’ property.
Now lets use see how this global object looks in the wild. Below is the line from my own app where i first use global.
// Some other class -(id) init { // always call "super" init // Apple recommends to re-assign "self" with the "super" return value if( (self=[super init] )) { Global *global = [Global instance]; global._difficulty = 1; global._useAccelerometer = YES; } // Or I can use it like this if i just need a quick varaible if([Global instance]._useAccelerometer == YES) //Tilt everything! return self; }
Ok that’s it, as always I’m learning as I go and sharing what I’ve learned for myself for future usage, and for anyone who might be interested. So feel free to point out any mistakes I have.
Tags: Uncategorized
Hey, i really like your articles, i was wondering if you could post a little tutorial about box2d collision callbacks!
Thanks!
Sure, I mean I barely understand them myself – however that’s a great excuse to learn more about them
This does not work! You should test it before you profess to know and spread misinformation and bad code.
Bobby could you explain which part fails, perhaps I left out some part of the code.
This does work for me, as i’m using it in my own apps. Perhaps there is a better alternative, which is entirely possible.
I was able to get this to work after making the following changes.
>>>
…
int _difficulty 0; <– remove 0
…
@property(nonatomic) int _diffculty; <– typo _difficulty
…
<<<
Hope that helps.
Ah, there it is.
Thanks greg, I’m still getting used to this laptop keyboard ))
Good info (even though you – and I – barely understand it)
It might be useful to add methods to the class that allows it to automatically load data from an encoded data object when it’s created/first accessed, and saves the data whenever a property is changed.
I currently use a data class in my app delegate that is available as a property to other parts of the code. When another part of the app makes a change to the data object (e.g., settings), the part of the code that’s doing the change must also tell the delegate to save the changes – sloppy.
In future apps I may implement the singleton instance method you described above.
Javy, that’s great I like your idea there.
Question, my understanding is that @synchronized locks code and protects it from being double-executed by multiple threads. Is that even needed for iPhone? Doesn’t iPhone OS only support a single thread in an application?