2015-02-05 138 views
1

我正在实施装饰模式与一个“包装”另一个类。具体细节并不重要,但我希望能够有选择地覆盖由UICollectionViewDataSource返回的值。所以我需要能够调用原始方法,然后修改其返回值。Objective-C装饰器模式,得到“方法定义未找到”

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

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

迈克·阿什描述了blog post此问题:

声明

的Objective-C公司的C遗产的另一个后果是,编译器需要知道每封邮件的方法的签名,你将会发送你的代码,甚至是纯粹转发的代码。为了让一个人为的例子,假设编写使用转发来自代码产生整数的一类,所以你可以这样写:

int x = [converter convert_42]; 

麻烦的是,编译器不知道任何convert_42方法,所以它不知道它返回什么样的价值。它会给你一个令人讨厌的警告,并假定它返回id。该修复程序很简单,只需要声明一个地方:

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

同样,这显然不是非常有用的事,但在你有一个更实际的转发情况下的情况下,这可以帮助你做出与和平编译器。例如,如果使用转发来伪造多重继承,则使用一个类别将其他类的所有方法声明为也适用于乘法继承类。这样编译器就知道它有两套方法。一组通过转发处理,但对编译器无关紧要。

我这样做,通过创建一个类的类别只有方法定义,但是编译器抱怨“找不到方法定义”,所以我想我误解了迈克写。

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

回答

2

我是这样做的,只用方法定义创建一个类别类别,但编译器抱怨“没有找到方法定义”,所以我想我误解了Mike写的东西。

如果您正确声明了您的类别,那么您将不会收到“未找到方法定义”警告。

例如:

@interface MyClass : NSObject 
@end 

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

只要没有相应的@implementation MyClass(MyForwardedMessages)块,那么你将不会看到有关-foo缺少的方法实现的警告。

+0

谢谢,我不知道你可以有一个没有'@ implementation'块的类别 – bcattle 2015-02-05 22:10:56