Thursday, 11 October 2012

Objective C Singletons

I was writing my first app in Objective C using Apple's wonderous XCode IDE.  I had two view controllers launched from the nib to control a couple of views.  I needed to send data from one controller to another and had real difficulty.  The problem was that I couldn't use accessors to pass data, as I would prefer, because the viewcontroller objects weren't aware of each other.  After much reading, googling and 'youtube tutorialing' I settled on using a 'Singleton' object.  This great youtube tutorial by barrowclough was particularly helpful.

A Singleton is a custom class you create that can be accessed by any other objects.  It is declared in such a way that different objects instantiate this class they all end up with the same object. This means that the variables/attributes/properties of the Singleton can be get/set by any of those objects.
First thing was to create a new class (add new file to the project in XCode).  Here is the code for the Singleton custom class:

Singleton.h

#import <Foundation/Foundation.h>
@interface Singleton : NSObject {
    NSMutableArray *passedMutableArray;
}
@property NSMutableArray* passedMutableArray;
+ (Singleton *) sharedSingleton;
@end


Singleton.m

#import "Singleton.h"
@implementation Singleton
@synthesize passedMutableArray;

static Singleton *sharedSingleton = nil;
+ (Singleton *) sharedSingleton {
    @synchronized(self) {
        if (sharedSingleton == nil){
            sharedSingleton = [[self alloc] init];
        }
    }
    return sharedSingleton;
}
@end

Any variables that you would like to be 'globally' accessible are added to these files in the same way as I have demonstrated with passedMutableArray that appears on two lines in .h and one in .m.  You can add as many variables as you like - I have chosen to show only one (passedMutableArray) in my example.

Every class that will use the Singleton must: #import "Singleton.h" in its .h file and then create a singleton object (also known as instantiate an object of class Singleton) somewhere in its implementation with this line of code:

Singleton* mySingleton = [Singleton sharedSingleton];

To 'send' data via the Singleton its simply a case of setting the value of the Singleton property (passedMutableArray) in the first object in my example i.e.:
mySingleton.passedMutableArray = localMutableArray;


To 'receive' that data in the other object is similarly straightforward e.g.:

otherLocalMutableArray = mySingleton.passedMutableArray;


That's it - this is how I sent my mutable array from one view controller object to another.

For clarity, both local variables must be of the right type, in this case defined within the {} of the .h file of the two viewcontroller classes:

In first object's class: NSMutableArray *localMutableArray;
In other object's class: NSMutableArray *otherlocalMutableArray;

Also, both of the objects I refer to as sending and receiving data via the Singleton can do both sending and receiving, it's a two way thing.  Also, you are not limited to just two object accessing the Singleton as the properties are available to any classes that instantiates this Singleton.



1 comment:

  1. I found an interesting but (for me) unfathomable post on this subject by LukeRedpath (http://lukeredpath.co.uk/blog/a-note-on-objective-c-singletons.html) - perhaps it's iOS specific? Added another potential solution to this problem.

    Luke does point to a post by Eschatology (http://eschatologist.net/blog/?p=178) that was less jargony but still too deeptech for me.

    I'm not criticising these guy's jargon or deeptech, I'm not their target audience... yet. In the meantime, if you're one of me (shallowtech? littoraltech? sinkingtech!?) it's well worth having to hand or harddrive Apple's Cocoa Fundamentals Guide: https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CocoaFundamentals

    Maybe that will demystify the jargon and deeptech I'm finding on this steep Xcode/Obj-C learning curve.

    ReplyDelete