Приведение класса в соответствие с протоколом с категорией для существующих методов
У меня есть протокол MyProtocol.
MyProtocol имеет требуемый метод:
- (NSUInteger)length;
И некоторые другие методы.
Теперь я хочу, чтобы класс NSString соответствовал MyProtocol с категорией. Например:
@interface NSString (NSStringWithMyProtocol) <MyProtocol>
@end
В этой категории я реализую все методы, исключая метод 'length', потому что мне нужна оригинальная реализация NSString.
Я не хочу переопределять его в этом конкретном классе.
Теперь я получаю предупреждение из-за неполной реализации MyProtocol в категории.
Я знаю, что есть несколько решений для решения этой проблемы.
- Сделать метод необязательным
- Указатель Swizzling
- Добавление подкласса к классу, который соответствует протоколу. Затем оставьте реализацию.
Я не хочу использовать эти параметры, потому что они приводят к плохому дизайну для остальной части моего кода.
Вариант 3 плох, поскольку существующие прямые подклассы не будут соответствовать протоколу.
Кто-нибудь знает, как удалить предупреждение, не применяя метод длины?
ПРИМЕЧАНИЕ. Класс, категория и протокол являются просто примерами. Я столкнулся с этой проблемой с другими классами, о которых я не мог опубликовать.
Благодаря
EDIT: Добавлен третий вариант.
Полный код:
Протокол:
@protocol MyProtocol <NSObject>
- (void) myMethod;
- (NSInteger) length;
@end
Заголовок категории:
#import <Foundation/Foundation.h>
#import "MyProtocol.h"
@interface NSString (MyProtocol) <MyProtocol>
@end
Реализация категории:
@implementation NSString (MyProtocol)
- (void)myMethod {
}
@end
В результате появляются следующие предупреждения.
Incomplete implementation
Method in protocol not implemented
На этом снимке экрана вы можете увидеть мое предупреждение:
![Screen shot]()
Я попробовал компиляцию с LLVM GCC 4.2 и компилятором Apple LLVM 3.0.
Я также скомпилировал на xcode 4.0.2 и Xcode 4.2.
Я на OS X 10.6.8.
Ответы
Ответ 1
Я не могу воспроизвести эту проблему. Можете ли вы опубликовать код, демонстрирующий его? Следующие компиляции без предупреждений на 10.7.
#import <Foundation/Foundation.h>
@protocol MyProtocol <NSObject>
- (NSUInteger)length;
@end
@interface NSString (NSStringWithMyProtocol) <MyProtocol>
@end
int main (int argc, const char * argv[]) {
@autoreleasepool {
id<MyProtocol> foo = @"foo";
NSLog(@"%@", foo);
}
return 0;
}
Ответ 2
Вы можете считать это немного взломанным, и я не знаю, будет ли он работать, но как объявить его как свойство только для чтения.
@property (readonly, assign) NSUInteger length;
а затем в реализации вашей категории сделайте @dynamic