Making class conform to protocol with category for existing methods

百般思念 提交于 2019-11-30 14:45:01

问题


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.

  1. Make the method optional
  2. Pointer Swizzling
  3. 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.


回答1:


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;
}



回答2:


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



来源:https://stackoverflow.com/questions/7255392/making-class-conform-to-protocol-with-category-for-existing-methods

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!