super allocWithZone having some doubts in singleton class concept

前端 未结 3 654
南旧
南旧 2021-02-06 08:25

I am new in Objective-C and I am trying to create a singleton class based on Apple\'s documentation.

+ (MyGizmoClass*)sharedManager
{
    if (sharedGizmoManager          


        
相关标签:
3条回答
  • 2021-02-06 08:57

    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.

    1. 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

    2. This one was throwing me off too. I asked this question and it was concluded:

      [super class] calls the super 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].

    3. Are you sure it's actually returning an instance of this class? Or are you assigning it to an instance sharedGizmoManager of this class?

    4. 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.

    0 讨论(0)
  • 2021-02-06 09:01

    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.

    0 讨论(0)
  • 2021-02-06 09:04

    (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.

    0 讨论(0)
提交回复
热议问题