> On Aug 12, 2015, at 8:07 PM, André Francisco <andre.frate...@hotmail.com> > wrote: > > Hi all, > I've been reading about object initialisation in Objective-c, as well as the > recent additions of NS_UNAVAILABLE and NS_DESIGNATED_INITIALIZER. It's been > confusing what the correct approach would be, mostly due to limitations > imposed by the compiler. My main goal is obviously to ensure proper object > initialisation, both when an object is directly instantiated and when a > constructor call is propagated by a child subclass. > It's noticeable that my background comes mostly from C++ and Java, both > languages in which constructors are not inherited by child classes, unlike > Objective-c. I can't make sense out of constructor inheritance, to be honest. > The fact that a constructor makes sense in a given class does not mean it > will to its children. -init is a great example of this if a given class has > mandatory parameters with no default values. > Lets analyse some approaches: > Override the parent constructor and make up some defaults - this is, IMO, the > worts approach. It'll force you to come up with defaults even if they are > senseless. Callers will have to rely on documentation in order to understand > what the defaults are doing, if anything at all. I've read about "set all to > zero" approaches but in this case enums come to mind. Obviously not only > enums will suffer from this, but setting an enum to zero does not mean that > it's an invalid state, quite the contrary. Even so, the instance would still > be useful so I really don't see a point.
> ,.. Instead of this approach I'd rather:Always return nil. If the parent's initializer cannot create a child object correctly, then having the child implement it and throw an exception is the right approach. It's a programmer error and should be treated as such. @implementation Child - (instancetype)initMethodFromParent { [self doesNotRecognizeSelector:_cmd]; return nil; } @end And now with NS_UNAVAILABLE, you would mark it as such in the @interface so the compiler will enforce it not being called. @interface Child : Parent - (instancetype)initMethodFromParent NS_UNAVAILABLE; @end > Use NS_UNAVAILABLE on constructors that do not provide required parameters > (ie., parameters without defaults). This would be my favourite approach as it > is enforced by the compiler if the method is called directly, except that you > cannot redefine the method on a subclass. Lets say a given class is > implemented and flags -init as NS_UNAVAILABLE, while implementing a second > initialiser -initWithParameter:. This is a base class and it doesn't make > sense not to provide the given parameter, whatever the reason may be. Some > other class, a child of the first, is not implemented which does provide a > default parameter - too late, -init is already unavailable. No, it's fine. Just declare the -init method as NS_DESIGNATED_INITIALIZER in the @interface of the child class, and implement it to call -initWithParameter: of the parent class. -- Seth Willits _______________________________________________ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com