Mister Smith
Mister Smith

Reputation: 28188

Best way of preventing other programmers from calling -init

When designing a class hierarchy, sometimes the subclass has added a new initWithSomeNewParam method, and it would be desirable to disable calls to the old init method inherited from the superclass.

First of all, I've read the question here, where the proposed alternatives are either override init to throw an exception at runtime, or override and set default values for properties. In my case, I don't wan't to provide default values, and I want to clearly indicate that the old method should not be called, and instead the new method with parameters should be used.

So the runtime exception are fine, but unless the code is debugged, there's no way for other programmers in the team to notice that the old method is no longer intended to be used.

If I'm correct, there's no way to mark a method as "private". So, apart from adding comments, is there a way to do this?

Thanks in advance.

Upvotes: 42

Views: 5983

Answers (5)

Andrew Paul Simmons
Andrew Paul Simmons

Reputation: 4523

The syntax has been shortened to just:

- (instancetype)init NS_UNAVAILABLE;

Upvotes: 0

RileyE
RileyE

Reputation: 11084

To add to what @DarkDust posted, you could alternatively use UNAVAILABLE_ATTRIBUTE

- (id)init UNAVAILABLE_ATTRIBUTE;

This will throw an error when a user tries to call init on an instance of this class.

Upvotes: 4

DarkDust
DarkDust

Reputation: 92384

You can explicitly mark your init as being unavailable in your header file:

- (id) init __unavailable;

or:

- (id) init __attribute__((unavailable));

With the later syntax, you can even give a reason:

- (id) init __attribute__((unavailable("Must use initWithFoo: instead.")));

The compiler then issues an error (not a warning) if someone tries to call it.

Upvotes: 108

Tony Million
Tony Million

Reputation: 4296

initWith:Stuff and:OtherStuff should never be more than convenience constructors.

In that they effectively should call

self = [self init];

if(self)
{
    self.stuff = Stuff;
    self.other = OtherStuff;
}

so [object init] will always return an object in a predefined state, and [object initWithStuff:stuff] will return the object in the predefined state with stuff overridden.

Basically what I'm getting at is, its bad practice to discourage [object init] especially when someone subclasses your subclass in the future….

Upvotes: 0

Jake
Jake

Reputation: 3973

Flag it deprecated? Developers will be developers, you can't stop us all! ;-)

How do I flag a method as deprecated in Objective-C 2.0?

Upvotes: 1

Related Questions