Resolved "Hiding" init method

Discussion in 'iOS Programming' started by MickeyT, Feb 18, 2013.

  1. MickeyT, Feb 18, 2013
    Last edited: Feb 20, 2013

    MickeyT macrumors member

    Joined:
    Apr 26, 2010
    Location:
    Newcastle, United Kingdom
    #1
    I have written a class where one of its instance variables needs to point to the object which created it. I have written an initWithName:andContainer method where one of the second argument requires an instance of the creating object. A weak pointer is then created to this "containing" object.

    Normally, I would also override the init method, call the above method and pass some dummy parameters. However, in this case I don't want init to be "available" because I can't pass a dummy parameter for the containing object. These objects must never be created without an "owning" container.

    Is there a way to stop init being available, or do I just set it up so that the init method returns nil which would, I assume, cause an exception to be thrown and thus force the use of the initWithName:andContainer method?

    Thank you
     
  2. ArtOfWarfare, Feb 18, 2013
    Last edited: Feb 18, 2013

    ArtOfWarfare macrumors 604

    ArtOfWarfare

    Joined:
    Nov 26, 2007
    #2
    Returning nil would not cause an exception to be thrown unless you somehow set it to throw yourself. In Obj-C, nil evaluates to zero and any calls to it will simply return zero.

    There's an answer on StackOverflow over here suggesting that you should throw an NSInternalInconsistencyException:

    http://stackoverflow.com/questions/...o-make-the-init-method-private-in-objective-c

    Edit: Actually, I think I like the answer below it more... doesNotRecognizeSelector: sounds like exactly what you want:

    http://stackoverflow.com/a/5772821/901641
     
  3. MickeyT thread starter macrumors member

    Joined:
    Apr 26, 2010
    Location:
    Newcastle, United Kingdom
    #3
    Sorry - what I meant was that when an attempt is subsequently made to use the object, I thought an exception would be thrown because the [super init] method would never have been called and so it wouldn't have been set up properly.

    But I realised just now that you're absolutely right - I coincidentally didn't initialise an NSString object just now, and when I use it there's no exception, it just doesn't work.

    Thanks for the reply - I'll have a look over those links and see if I'm happy before resolving the thread.

    Many thanks.
     
  4. PhoneyDeveloper macrumors 68030

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #4
    I wouldn't call [self release] and then [super whatever] since you'll probably be dealloced from the [self release] call. At any rate, it's neurotic to be trying to do memory management to avoid a memory leak when on the next line you're going to deliberately crash your app, as suggested in one of those links.

    Any of the suggested solutions is fine.
     
  5. ArtOfWarfare macrumors 604

    ArtOfWarfare

    Joined:
    Nov 26, 2007
    #5
    Not necessarily... you could catch the exception somewhere, could you not?
     
  6. PBG4 Dude macrumors 68000

    PBG4 Dude

    Joined:
    Jul 6, 2007
    #6
    If I understand you correctly, you're saying that Object A instantiates Object B and requires a pointer to Object A?

    If so, you should set up Object A to be a delegate of Object B.
     
  7. MickeyT, Feb 19, 2013
    Last edited: Feb 19, 2013

    MickeyT thread starter macrumors member

    Joined:
    Apr 26, 2010
    Location:
    Newcastle, United Kingdom
    #7
    Forgive me - what is the difference between what I am doing and setting up as a delegate?

    Whenever I have set something as the delegate of something else, I was under the impression that "delegate" was just the name that was given to the instance variable I was assigning the object to (and I was using the setter method setDelegate to do that). In this case, that's what I do, but my instance variable isn't called "delegate", it is called something else.

    And I am doing this via an init method, because I absolutely want this to always happen.
     
  8. dejo, Feb 19, 2013
    Last edited: Feb 19, 2013

    dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #8
    Delegation usually has a protocol associated with it. And delegate methods that may need to be implemented. All you're doing, I believe, is capturing a simple relationship between two objects, a parent-child one, as it were.
     
  9. MickeyT thread starter macrumors member

    Joined:
    Apr 26, 2010
    Location:
    Newcastle, United Kingdom
    #9
    That's right. Whether what I'm doing is a good way or a bad way to achieve what I'm setting out to do is possibly irrelevant at this stage; I want to do it so that if it turns into a nightmare then I will learn from that.

    Essentially, I might end up with a hierarchy of perhaps three or four levels. When I'm down at level four, I want to be able to access instance variables at level one if the situation warrants it. Chances are the view controller dealing with the level four object won't have any knowledge of the level one object, and so I was thinking I would need a way of moving up and down the chain without having to bring the level one object with me everywhere.

    That might not make sense - the app is going to be navigation controller based and so I was making my model layer to sort of follow the same drill down convention.
     
  10. Duncan C macrumors 6502a

    Duncan C

    Joined:
    Jan 21, 2008
    Location:
    Northern Virginia
    #10

    One of the stack overflow links posted by another poster suggested adding a compiler directive that would throw a compile-time error:

    -(id)init __attribute__((unavailable("init not available")));

    That seems like the best option to me. You get warned at compile time so you know not to use the init method.
     
  11. MickeyT thread starter macrumors member

    Joined:
    Apr 26, 2010
    Location:
    Newcastle, United Kingdom

Share This Page