Re: What classes have -init?
Re: What classes have -init?
- Subject: Re: What classes have -init?
- From: Charles Srstka <email@hidden>
- Date: Thu, 11 Feb 2010 23:07:14 -0600
On Feb 11, 2010, at 10:28 PM, Graham Cox wrote:
> On 12/02/2010, at 1:43 PM, Gordon Apple wrote:
>
>> My point was that if all Cocoa classes called "init"
>> somewhere in their other initializers (or had a two-step initialization
>> similar to what MacApp did), then you could simply override (not call)
>> "init" for simple ivar initialization in a subclass, which would in no way
>> interfere with a designated initializer.
>
>
> Except that it would be all too easy to create an infinite loop. A subclass might implement -init to call super's designated initializer, which later calls -init.
>
> I'm not sure what's complex about overriding the designated initializer - even if it has a complex set of parameters, (and most do not) then all you do is pass them up to super. Your suggestion would only save a tiny, tiny amount of work yet lead to potentially big problems.
>
> --Graham
Not really; suppose you want to subclass some class that has two separate init methods:
- (id)initWithFoo:(Foo *)foo;
- (id)initWithBar:(Bar *)bar;
and suppose you just want to set some initial internal state, which needs to always be set the same way at init time no matter how the object is initialized. Which init method do you override? It’s possible that the “initWithFoo:” method may look like this:
- (id)initWithFoo:(Foo *)foo
{
return [self initWithBar:[SomeClass convertAFooToABarSomehow:foo]];
}
in which case you’d just need to override initWithBar:. However, what happens if it’s actually the other way around, and initWithBar: looks like this:
- (id)initWithBar:(Bar *)bar
{
return [self initWithFoo:[SomeClass convertABarToAFooSomehow:bar]];
}
Knowing which is which requires you to have knowledge of the parent object’s code. And what if the implementation of the parent changes over time from one of the above scenarios to the other? Clearly the only way to make sure your init *always* gets called is to override init, initWithFoo:, *and* initWithBar:, and if there are more than just two initializers, this can get quite cumbersome. And even then, what happens if the superclass gets updated so that a third initializer gets added:
- (id)initWithBaz:(Baz *)baz;
which doesn’t happen to call initWithFoo: *or* initWithBar:? Now your custom init won’t get called at all if that initializer is used.
Incidentally, there is just such a class in Cocoa: NSDocument. It provides six different init methods:
- (id)init;
- (id)initForURL:(NSURL *)absoluteDocumentURL withContentsOfURL:(NSURL *)absoluteDocumentContentsURLofType:(NSString *)typeName error:(NSError **)outError;
- (id)initWithContentsOfURL:(NSURL *)absoluteURL ofType:(NSString *)typeName error:(NSError **)outError;
- (id)initWithType:(NSString *)typeName error:(NSError **)outError;
- (id)initWithContentsOfFile:(NSString *)fileName ofType:(NSString *)docType;
- (id)initWithContentsOfURL:(NSURL *)aURL ofType:(NSString *)docType;
Yes, the last two of these are deprecated, but it’s still possible that they could get called, so you’d still have to take that into account. Interestingly, though, someone at Apple appears to agree with Gordon here, since all of those NSDocument initializers actually seem to call -[self init] instead of -[super init], with the result that you can in fact just override -init instead of having to override all six methods separately (and the NSDocument subclass template even includes an -init method, to further encourage this).
Charles_______________________________________________
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