Reputation: 1832
I have two methods in my class
- (void)configureWithDictionary:(NSDictionary*)dictionary;
- (void)configureWithDictionary:(NSDictionary*)dictionary withOptions:(XWTreeItemConvertationToNSDictionaryOption*)options;
And I have implementation for both of them. So! Solution like: "Just add NSAssert(NO, @"You mast override this method")" will not help =(
- (void)configureWithDictionary:(NSDictionary*)dictionary withOptions:(XWTreeItemConvertationToNSDictionaryOption*)options;
{
NSAssert(NO, @"You mast override this method"
}
Because I have some code over there. And need to write [super configureWithDictionary:dictionary withOptions:options];
in overloaded method.
Everyone can use this methods. And I need both! But.
If some developer will overload -[MYClass configureWithDictionary:]
it can "work incorrect". Just because this method doesn't call any time. So I need to write something in console. Like: "Please overload method: -[MYClass configureWithDictionary:withOptions:]
". And I want to handle it only once in this method:
+ (void)initialize
{
if (self == [self class]) {
}
}
But I can't find any solution(in documentation/google/stackoverflow). And can't handle: "Does developer overload method of base class".
May be there are some better solution. But I think it should be the best. If you have some another ideas. Please write bellow =)
I've found only method: +[NSObject instancesRespondToSelector]
and of course I know about -[NSObject respondsToSelector:]
but as you know it always return YES. I need almost same, but for current class ignoring base.
PS. Any way thanks for your attention. Link to documetation or some article will be very helpful.
Upvotes: 2
Views: 130
Reputation: 1832
I've found solution myself and I think it can help community. So 3 Simple steps.
Step 1: Create category form NSObject with method
+ (NSArray*)methodNamesForClass_WithoutBaseMethodsClasses
{
unsigned int methodCount = 0;
Method *methods = class_copyMethodList(self, &methodCount);
NSMutableArray *array = [NSMutableArray arrayWithCapacity:methodCount];
for (unsigned int i = 0; i < methodCount; i++) {
Method method = methods[i];
[array addObject:[NSString stringWithFormat:@"%s", sel_getName(method_getName(method))]];
}
free(methods);
return [array copy];
}
Step 2: Check does you class overload some method:
[[self methodNamesForClass_WithoutBaseMethodsClasses] containsObject:NSStringFromSelector(@selector(configureWithDictionary:))]
Step 3: Check all what you need in + (void)initialize
. It called once for class(so it will not a lot of CPU time). And it needed only for developers. So Add #ifdef DEBUG
directive
+ (void)initialize
{
if (self == [self class]) {
#ifdef DEBUG
if ([[self methodNamesForClass_WithoutBaseMethodsClasses] containsObject:NSStringFromSelector(@selector(configureWithDictionary:))] && ![[self methodNamesForClass_WithoutBaseMethodsClasses] containsObject:NSStringFromSelector(@selector(configureWithDictionary:withOptions:))]) {
NSAssert(NO, @"Please override method: -[%@ %@]", NSStringFromClass([self class]), NSStringFromSelector(@selector(configureWithDictionary:withOptions:)));
}
#endif
}
}
Victory!
Upvotes: 0
Reputation: 4615
May be it's not exactly what you are asking, but when I need to be sure that child classes overload some required method I do such thing:
@protocol SomeClassRequiredOverload
- (void) someMethodThatShouldBeOverloaded;
@end
@interface _SomeClass
@end
typedef _SomeClass<SomeClassRequiredOverload> SomeClass;
Upvotes: 2