RE: Initialisation pattern
RE: Initialisation pattern
- Subject: RE: Initialisation pattern
- From: André Francisco <email@hidden>
- Date: Thu, 13 Aug 2015 20:32:23 +0000
- Importance: Normal
I only got Seth's email on the digest, not really sure why. Anyway, I copy pasted his response below.@Seth, thank for your answer. That's exactly what I've been doing all along, I didn't mention it because that's precisely what I'm trying to change. The problem is that it's not fine, I just tested it:@interface Parent- (instancetype)init NS_UNAVAILABLE;@end@interface Child- (instancetype)init NS_DESIGNATED_INITIALIZER;@endThis results in "init is unavailable" being issued by the compiler when instantiating Child. I'm using xcode 6.3.2, does your version differ?
> 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
From: email@hidden
To: email@hidden
Subject: RE: Initialisation pattern
Date: Thu, 13 Aug 2015 03:48:17 +0000
I've read that too :) still, the problem sticks. I'm writing a framework, not an app, so it's important that callers initialise objects properly. And I wish I was using swift, honestly.
Subject: Re: Initialisation pattern
From: email@hidden
Date: Wed, 12 Aug 2015 20:22:36 -0700
CC: email@hidden
To: email@hidden
On Aug 12, 2015, at 8:07 PM, André Francisco <email@hidden> wrote: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.
Don’t sweat it — you may be overthinking this. In practice it’s not a big problem (I’ve only run into issues related to this a few times), and in the long run it’s fixed by Swift.
—Jens
_______________________________________________
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