Re: Initialisation pattern
Re: Initialisation pattern
- Subject: Re: Initialisation pattern
- From: Seth Willits <email@hidden>
- Date: Thu, 13 Aug 2015 08:15:06 -0700
> On Aug 12, 2015, at 8:07 PM, André Francisco <email@hidden> 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 (email@hidden)
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:
This email sent to email@hidden