Objective-C 装饰器模式,得到 "Method definition not found"

Objective-C decorator pattern, getting "Method definition not found"

我正在用一个 class 那个 "wraps" 另一个来实现装饰模式。具体细节并不重要,但我希望能够有选择地覆盖由 UICollectionViewDataSource 编辑的值 return。所以我需要能够调用原始方法,然后修改它的 return 值。

我正在使用 forwardingTargetForSelector: 将任何无法识别的消息转发到包装的对象。

问题是 XCode 抱怨它找不到任何转发消息的方法定义,并输出大量警告。

Mike Ash 在 blog post 中描述了这个问题:

Declarations

Another consequence of Objective-C's C heritage is that the compiler needs to know the full method signature of every message that you're going to send in your code, even purely forwarded ones. To make a contrived example, imagine writing a class that uses forwarding to produce integers from code, so that you can write this:

int x = [converter convert_42];

The trouble is that the compiler doesn't know about any convert_42 method, so it has no idea what kind of value it returns. It will give you a nasty warning, and will assume that it returns id. The fix to this is simple, just declare one somewhere:

@interface NSObject (Conversion)
- (int)convert_42;
- (int)convert_29;
@end 

Again, this obviously isn't very useful to do, but in cases where you have a more practical forwarding situation, this can help you make peace with the compiler. For example, if you use forwarding to fake multiple inheritence, use a category to declare all of the methods of the other class as applying to the multiply-inheriting class as well. That way the compiler knows that it has both sets of methods. One set gets handled by forwarding, but that doesn't matter to the compiler.

我通过创建一个仅包含方法定义的 class 类别来做到这一点,但是编译器在抱怨 "method definition not found" 所以我想我误解了 Mike 所写的内容。

如何摆脱这些警告?我可以用不同的方式构造装饰器 class,还是只需要直接用 #pragma 来抑制警告?

I did this, by creating a class category with just method definitions, but the compiler is complaining "method definition not found" so I think I misunderstood what Mike was writing.

如果您正确声明了 class 类别,那么您将不会收到 "method definition not found" 警告。

例如:

@interface MyClass : NSObject
@end

@interface MyClass(MyForwardedMessages)
- (void)foo;
@end

只要没有相应的 @implementation MyClass(MyForwardedMessages) 块,您就不会看到有关 -foo.

缺少方法实现的警告