- (void)doIt
{
[_foo bar];
// produces compile time error: "No visible @interface for 'FooClass'
// declares the selector 'bar'"
}
在Objective-C的早期阶段,当我调用编译器不知道的方法时,我会收到警告。然后,就像一年前,编译器发生了变化,这样的事情现在变成了错误。有人知道这件事何时发生(__weak
?)
我知道有几种方法可以解决这个问题。但是,我希望有一种更简单的方法。
@interface FooClass (MichaelHacksIt)
- (void) bar;
@end
// ...
- (void) doIt
{
[_foo bar];
}
-performSelector:
- (void)doIt
{
[_foo performSelector:@selector(bar)];
}
因为解决方案B有时会产生“未声明的选择器”警告,并且因为我们不希望Apple知道我们正在调用哪些方法,所以始终有第三种解决方案:
- (void)doIt
{
SEL bar_sel = NSSelectorFromString(@"bar");
[_foo performSelector:bar_sel];
}
如果方法调用的参数不仅仅是对象,我们需要使用NSInvocation
。那太难看了。
是否有一些编译器开关可以禁用错误?在引擎盖下,消息发送始终只是对objc_msgSend()
的调用,并且链接到方法实现是在运行时完成的。因此,原则上应该可以禁用错误。我想做的是类似于:
- (void)doIt
{
#pragma clang diagnostic push
#pragma clang error disable objc_method_unknown_error
[_foo bar];
#pragma clang diagnostic pop
}
有这样的编译时间开关吗?是否可以在命令行传递生成此行为的编译器标志?
当您尝试使用未记录的方法时会出现这些问题。例如change the status bar text color in iOS。或者当你有源代码时override some undocumented method in a subclass,但你不想因为某些原因修改它。
我的解决方案A在运行时是否有任何影响?是否有可能以某种方式在二进制文件中看到我声明了一个私有类别(MichaelHacksIt
)或它是否只是使编译器静音? (请注意,此类别没有@implementation
。)
我的主要问题是:是否可以禁用“没有可见的@interface为'SomeClass'声明选择器'fooBar'”?