Making class conform to protocol with category for existing methods
I have a protocol named MyProtocol. MyProtocol has an required method:
- (NSUInteger)length;
And some other methods.
Now i want to make the NSString class conform to MyProtocol with a category. Like so:
@interface NSString (NSStringWithMyProtocol) <MyProtocol>
@end
In this category i implement all methods excluding the 'length' method, because i want the original NSString implementation. I do not want to override it in this particular class.
Now i get a warning because of an incomplete implementation of MyProtocol in the category.
I know there are a few solutions to solve this.
- Make the method optional
- Pointer Swizzling
- Adding subclass to class which is conform to the protocol. Then leave out the implementation.
I do not want to use these options because they result in a bad design for the rest of my code.
Option开发者_如何转开发 3 is bad, because of existing direct subclasses will not be conform to the protocol.Does anybody know how to remove the warning without implementing the length method?
NOTE: The class, category and protocol are just examples. I did encounter this problem with other classes which i could not post about. Thanks
EDIT: Added the third option.
Full Code:
The protocol:
@protocol MyProtocol <NSObject>
- (void) myMethod;
- (NSInteger) length;
@end
The category header:
#import <Foundation/Foundation.h>
#import "MyProtocol.h"
@interface NSString (MyProtocol) <MyProtocol>
@end
The category implementation:
@implementation NSString (MyProtocol)
- (void)myMethod {
}
@end
This results in the following warnings.
Incomplete implementation
Method in protocol not implemented
In this screenshot you can see my warning:
I tried compiling with LLVM GCC 4.2 and the Apple LLVM 3.0 compiler. I also compiled on xcode 4.0.2 and Xcode 4.2. I'm on OS X 10.6.8.
I cannot reproduce this issue. Can you post code that demonstrates it? The following compiles without warnings on 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;
}
You might consider this a bit of a hack, and I don't know if it will even work, but how about declaring it as a read only property
@property (readonly, assign) NSUInteger length;
and then in the implementation of your category, make it @dynamic
精彩评论