In a subclasses interface, I declare a method, implemented by the superclass, as returning a different object type, since the subclass is specialized. However, there is no need for me to actually implement the method in the subclass - the superclass's implementation works fine. Unfortunately, this pattern now seems to give me the Method definition for … not found error
on recent versions of Xcode.
I am aware that I can turn off all such warnings by disabling -Wincomplete-implementation
with a diagnostic push
and pop
around the @implementation
, but I'd rather not take such an extreme approach, as the warning is useful in other contexts. (If this can mark individual methods to be silenced, I'm all ears)
Here is one of several example implementations that exhibit this problem:
Test.h
@interface GeneralItem : NSObject
@end
@interface GeneralGroup : NSObject
- (GeneralItem *)item;
@end
@interface ItemA : GeneralItem
@end
@interface GroupA : GeneralGroup
- (ItemA *)item;
@end
Test.m
#import "Test.h"
@implementation GeneralGroup
- (GeneralItem *)item
{
return nil;
}
@end
@implementation GroupA
// Warning: Method definition for 'item' not found
@end
To be clear, everything compiles and works fine, and to my understanding, the compiler should know that the superclass implements this method, not to mention Objective-C is not too picky about type-overloading in method definitions.
I'd like to avoid implementing the method and simply calling super
, as I see it as completely redundant code, but if someone can confirm to me that the compiler will optimize away a direct call to super
so the runtime can do its usual thing without needing to make a pitstop to the subclass, and that's the only way to silence this warning, then so be it.
Edit 1
Here are a few other scenarios where this comes up.
The first is a scenario where a common base class (or abstract superclass) implements a shared implementation of something with, say, blocks, but we only want some subclasses to selectively declare their support for it, with types properly annotated:
BlockTest.h
@interface GeneralItem : NSObject
@end
@interface GeneralGroup : NSObject
@end
@interface ItemA : GeneralItem
@end
@interface GroupA : GeneralGroup
- (void)loadItemWithCompletionHandler:(void (^)(ItemA *item))completionHandler;
@end
@interface ItemB : GeneralItem
@end
@interface GroupB : GeneralGroup
- (void)loadItemWithCompletionHandler:(void (^)(ItemB *item))completionHandler;
@end
BlockTest.m
#import "BlockTest.h"
@interface GeneralGroup ()
- (id)item;
- (void)loadItemWithCompletionHandler:(void (^)(Item *item))completionHandler;
@end
@implementation GeneralGroup
- (void)loadItemWithCompletionHandler:(void (^)(Item *item))completionHandler;
{
if (completionHandler) completionHandler(self.item);
}
@end
@implementation GroupA
// Warning: Method definition for 'loadItemWithCompletionHandler:' not found
// A custom implementation of -item can be here, for instance
@end
I should note, you get no warning if you declare the method as - (void)loadItemWithCompletionHandler:(void (^)(Item *item))completionHandler;
in the public header in GroupA
, but you do get the "method definition not found" warning when you change the type to be a subclass of the originally-specified type.
The second is where you simply want to give more context to a superclass-provided method (using NSObject
's copy
here, but this applies to any method typed as id
that we would like to re-declare with more accurate types, so things like property-chaining work a bit less painlessly):
Subclass.h
@interface Subclass : NSObject
- (instancetype)copy;
@end
Subclass.m
#import "Subclass.h"
@implementation Subclass
// Warning: Method definition for 'copy' not found
@end