I am new in Objective-C and I am trying to create a singleton class based on Apple\'s documentation.
+ (MyGizmoClass*)sharedManager
{
if (sharedGizmoManager
The other answers, though they point out good information with regard to singletons, didn't actually answer your question. Your question is actually mostly based on Object orientation, the fact that you specifically reference a singleton is incidental.
I answered this question with reference to self
, here is the paraphrased, important part of the answer
super
does have meaning in class level contexts, but it refers to the superclass itself, not an instance
This one was throwing me off too. I asked this question and it was concluded:
[super class]
calls thesuper
method on the current instance (i.e.self
). If self had an overridden version, then it would be called and it would look different. Since you don't override it, calling[self class]
is the same as calling[super class]
.
Are you sure it's actually returning an instance of this class? Or are you assigning it to an instance sharedGizmoManager
of this class?
Super isn't equal to self, but some of the methods you have called: e.g. [super class]
is calling the same implementation of the method that [self class]
would call.
There is a couple of things to consider here. First, the Cocoa Fundamentals guide is somewhat out-of date. It doesn't take into account some of the current technologies Apple has developed, like Grand Central Dispatch, and Automated Reference Counting. The [retain] in your allocWithZone method would not compile correctly in a ARC-enabled project (since you're new to Obj-C, I'm making an assumption here you're new to iOS/iPhone as well, and so you should read up on those two technologies).
There is a very good discussion of different singleton design patterns over in this thread: What should my Objective-C singleton look like?
However that is an older thread, and as such does not take into account Automated Reference Counting (I've utilized Louis Gerbang's answer for years and it no longer works in ARC-enabled projects).
For ARC-enabled projects/files (yes ARC can be enabled just for single files) - we've moved to a singleton that uses GCD and works quite well:
static YourClassName * volatile sharedInstance = nil;
+ (YourClassName *)sharedInstance
{
static dispatch_once_t sharedInstanceToken;
dispatch_once(&sharedInstanceToken, ^{
sharedInstance = [[YourClassName alloc] init];
});
return sharedInstance;
}
What's going on here? Well if you take a look through the GCD docs, you'll see dispatch_once only gets executed once during the entire lifetime of an application for a particular object. As the docs go onto say, this makes it very useful for creating singletons in a thread-safe manner.
On top of that, we declare the sharedInstance method as volatile, meaning the compiler/runtime should never try to cache a call to the method and should always execute the code inside. This makes sure we always call into GCD and that we always get back the object we're supposed to.
I'm glossing over a bunch since you're new to Obj-C, but definetly take a look into GCD, ARC, and then once you've got a solid grounding in Obj-C, looking into IMP caching, which is what volatile is preventing from happening.
(1.) What is super
in a 'static function'? In Objective-C, +methods are properly called class methods, -methods are called instance methods. These +methods are not true static methods because Objective-C classes are themselves objects of an opaque type called Class. So both super
and self
are defined in +methods. super
sends messages to the superclass of MyGizmoClass, but when called from a +method super
looks for an equivalent +method, and when called from an -method super
looks for a corresponding -method.self
in +methods of MyGizmoClass returns MyGizmoClass which is a Class, whereas in -methods self
is a pointer to a MyGizmoClass instance.
(2.) The method +class
returns self.isa
. Yes [super class]
invokes the superclass's:+class
method, however, when self
is passed up to +methods neither its value nor its type are modified (whereas self
's type is cast to the superclass when it is passed up through -methods). So when an implementation of the +class
method up the chain asks for self.isa
, it gets the same value, MyGizmoClass.
To be certain, you can verify that super
does call +class
in superclasses by deriving MyGizmoClass from a MyGizmoSuperClass where you can place an override:
@interface MyGizmoSuperClass : NSObject
@end
@implementation MyGizmoSuperClass
+(Class) class {
NSLog(@"yes it calls MyGizmoSuperClass:class");
return [super class];
}
@end
@interface MyGizmoClass : MyGizmoSuperClass
+(Class) classviasuper;
@end
@implementation MyGizmoClass
+(Class) classviasuper {
return [super class]; //which version of class will super call?
}
@end
int main(int argc, char *argv[])
{
NSLog(@"returned %@",[MyGizmoClass classviasuper]);
}
prints
yes it calls MyGizmoSuperClass:class
returned MyGizmoClass
(3.) Again super
calls the superclass version of allocWithZone
but the self
value passed to the method still points to a MyGizmoClass, and since allocWithZone
returns an object of the receiver's class, you get a MyGizmoClass back.
(4.) You can easily verify super
is different to self
. If you implement [self allocWithZone:NULL]
your code will call MyGizmoClass's implementation of allocWithZone
and loop indefinitely. With [super allocWithZone:NULL]
, the superclass's version gets called.