In my project I have 3 classes, let’s call them Apple, Orange and Pear.
Apple and Orange both have delegate properties.
They both define protocols in their header file called AppleDelegate and OrangeDelegate.
They each have initializers with similar signatures:
- (id)initWithDelegate:(id<AppleDelegate>)delegate
- (id)initWithDelegate:(id<OrangeDelegate>)delegate
Pear implements OrangeDelegate and is defined as follows:
@interface Pear : NSObject <OrangeDelegate>
Inside Pear, I make this call:
Orange *anOrange = [[[Orange alloc] initWithDelegate:self] autorelease];
That results in this compiler warning:
Class 'Pear' does not implement the 'AppleDelegate' protocol
It appears to me that the compiler does not recognize the protocols in the initializers. In other words, it only recognizes this signature for both:
- (id)initWithDelegate:(id)delegate
Because when I click “Jump To Definition” on the initializer in Pear, it brings up both classes as options.
Is there any way to correct this warning aside from renaming my methods?
The problem is that ‘alloc’ is a method inherited from NSObject, defined to return type ‘id’. So the following:
Evaluates to an object of type ‘id’. When you then call initWithDelegate on that object, the compiler doesn’t know the type and in this case guesses the incorrect one. So you can eliminate the warning with:
So, basically, it’s because constructors aren’t a language level feature in Objective-C, merely a convention.
EDIT: see below; I guess another solution would be to add:
To Orange, which would be nothing more complicated than:
I guess it is partly a design decision — should classes be responsible for knowing that their constructor methods may clash with the names of other classes or should files that import multiple class definitions with the same constructors be responsible for disambiguating. Though the simple look of the syntax may be the clincher.