好的,这就是我找到的解决方案......一旦您知道该怎么做,结果就会变得非常简单。首先覆盖 '- (id)forwardingTargetForSelector:(SEL)aSelector' 并返回 iVar:
- (id) forwardingTargetForSelector:(SEL)aSelector{
return iVar;
}
当运行时正在寻找一个方法但找不到时,它将调用该方法来查看是否有另一个对象可以将消息转发到。请注意,此方法通常返回 nil,如果您在此处返回 nil,您的程序将崩溃(这是适当的行为)。
问题的第二部分是当您尝试发送未声明的消息时关闭编译器错误/警告。通过声明您未实现的类别可以轻松完成此操作。
@interface Class (iVarClassMethods)
@propoperty (strong) Class *property1;
......more properties
@end
只要你不在任何地方实施,又名@implementation Class (category)
,编译器不会抱怨(它会假设实现是某处....).
现在我看到的唯一缺点是,如果您更改 iVar 类接口中的任何属性,您需要确保更新使用上述方法的所有其他类,否则当另一个类尝试发送时您会崩溃现在什么是错误的方法(编译器不会提前警告你)。然而,这can被绕过。您可以在类别中声明协议。因此,您可以为 iVar 类创建一个单独的协议,并将所需的方法/属性从 iVar 类移至该协议中。
@protocol iVarClassProtocol
@propoperty (strong) Class *property1;
......more properties
@end
将该协议添加到 iVar 子类中,以便它现在具有通过协议声明的这些方法。
@interface iVarClass <iVarClassProtocol>
....other methods/properties you don't need forwarded
@end
最后,只需将协议添加到类别中即可。因此,您将拥有以下内容,而不是前面提到的带有显式声明的类别:
@interface Class (iVarClassMethods) <iVarClassProtocol>
@end
现在,如果您需要更改任何要转发的属性/方法,您可以在协议中更改它们。当您尝试向转发类发送错误的方法时,编译器会警告您。