Методы в супер, которые все равно будут разделены на подклассы (Какао) - PullRequest
3 голосов
/ 05 апреля 2010

Извините, если это репост, но я не смог его найти, потому что не могу объяснить это в нескольких словах. У меня есть суперкласс с множеством методов, но они всегда (не все) будут разделены на подклассы. Из супер мне нужно запустить эти методы. Я мог бы либо оставить методы в супер пустом, либо просто не набирать их в super, но в любом случае вызывать их как [self myMethod], и он вызовет мой метод подкласса, даже если он не существует в super. Это работает, но Xcode дает мне ошибку, хотя. 'superclass' may not respond to '-subclassmethod'

Что мне делать, чтобы я не получал предупреждения?

Ответы [ 4 ]

4 голосов
/ 05 апреля 2010

Я предпочитаю определять нереализованные методы в суперклассе так:

@interface GLObject : NSObject {}
- (id)someSubclassProvidedMethod;
@end

@implementation GLObject
- (id)someSubclassProvidedMethod {
  [self doesNotRecognizeSelector: _cmd];
}
@end

Это почти полностью избыточно, потому что среда выполнения Objective C в конечном итоге вызовет -doesNotRecognizeSelector:, если я вообще не определю метод. Но поскольку я определил его, он находится в интерфейсе класса, который не только радует компилятор, но и предоставляет мне некоторую документацию.

1 голос
/ 05 апреля 2010

Мое решение было немного странным, но вот оно:

@protocol JSDog <NSObject>
- (void)yipe;
@end

@interface JSDog : NSObject
@end

@implementation JSDog

+ (void)initialize {
  if ([self isSubclassOfClass:[JSDog class]] && ![self conformsToProtocol:@protocol(JSDog)]) {
    NSAssert(false, @"Subclasses of JSDog must conform to <JSDog>.");
  }
}

@end

Наличие протокола с тем же именем, что и у класса, предшествует NSObject. Поскольку методы в формальном протоколе a по умолчанию @required, вы будете защищены с обеих сторон: в время компиляции , если ваш JSDog подкласс претендует на соответствие <JSDog>, но не внедрите -yipe, вы получите ошибку; в время выполнения , если ваш подкласс не претендует на соответствие <JSDog>, вы получите предупреждение при создании экземпляра подкласса.

1 голос
/ 05 апреля 2010

Вместо суперкласса вы можете объявить методы в протоколе , который в других языках называется "интерфейсом".

@protocol MyProtocol
-(id)myMethodWith:(id)arg;
@end

Измените объявление типа переменных, чтобы объявить, что объект соответствует протоколу.

-(id)doStuffWith:(SuperClass <MyProtocol> *)aThing and:(id)another {
    return [aThing myMethodWith:another]
}

Обратите внимание, что вы не сможете передать экземпляр своего суперкласса в doStuffWith:and:, поскольку он не будет реализовывать MyProtocol, но, похоже, это то, что вам нужно.

0 голосов
/ 05 апреля 2010

В последнее время мне нравится использовать NSAssert для этой задачи:

- (BOOL)proceedForVersion:(int)versionInteger
{
    NSAssert(false, @"This method needs to be overridden in a subclass of iMBApertureAbstractParser");

    return NO;
}
...