抑制 Xcode 中未找到类方法的警告

发布于 2024-12-02 18:32:18 字数 384 浏览 2 评论 0原文

我有一个类,其方法是在运行时确定的,如我的问题此处。这很好用,但现在我的代码中出现了一堆如下所示的警告:

Class method '+objectIsNotNil:' not found (return type defaults to 'id')

虽然这些警告实际上并不影响构建过程,但它们非常烦人,并且使发现相关警告变得更加困难。有没有办法禁用它们,但仅限于 Assert 类(可能是某种宏)?如果这是不可能的,那么是否有某种方法可以在整个构建过程中关闭它们?

I have a class whose methods are determined at runtime, as indicated in my question here. This works great, but now I have a bunch of warnings that look like the following littering my code:

Class method '+objectIsNotNil:' not found (return type defaults to 'id')

While these warnings don't actually affect the build process, they're very annoying and make it harder to spot relevant warnings. Is there some way to disable them, but only for the Assert class (maybe some kind of macro)? If this isn't possible, then is there some way to turn them off for the entire build?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

笑,眼淚并存 2024-12-09 18:32:18

一种替代方法是使用 PerformSelector:withObject: 而不是直接方法调用。
因此,

[Assert objectIsNotNil:object];

您可以使用:

[Assert performSelector:@selector(objectIsNotNil:) withObject:object];

它看起来不太好,但会删除警告。此外,此模式适用于您想要的任何选择器。为了让事情看起来更好一点,您可以按以下方式使用宏:

#define ASSERT_PRECONDITION(sel, obj)  [Assert performSelector:@selector(sel) withObject:obj]

这样您的断言将如下所示:

ASSERT_PRECONDITION(objectIsNotNil:, object);

One alternative would be to use performSelector:withObject: instead of the direct method call.
So instead of:

[Assert objectIsNotNil:object];

You could have:

[Assert performSelector:@selector(objectIsNotNil:) withObject:object];

It does not look quite as nice but it will remove the warnings. Furthermore, this pattern will work for any selector you want. To make things look a little better you could use macros in the following way:

#define ASSERT_PRECONDITION(sel, obj)  [Assert performSelector:@selector(sel) withObject:obj]

This way your assert would look like this:

ASSERT_PRECONDITION(objectIsNotNil:, object);
断念 2024-12-09 18:32:18

这些情况应该非常罕见......

我已经声明了一个隐藏协议,它声明了具有正确签名的方法。 “隐藏”是指它仅包含在需要它们的翻译中。

@protocol MONRuntimeClassInterface
+ (BOOL)objectIsNotNil:(id)object;
@end

these cases should be extremely rare...

I've declared a hidden protocol which declared the methods with proper signatures. 'Hidden' in the sense that it was only included by the translations which needed them.

@protocol MONRuntimeClassInterface
+ (BOOL)objectIsNotNil:(id)object;
@end
自由如风 2024-12-09 18:32:18

简单回答:

您不想这样做。如果我正确理解你的问题,你就不需要这样做。您正在链接中描述的 Predicate 类中定义所有相关方法,而 Assertion 只是转发给它们。包括 Predicate.h 并确保接口中声明的所有内容都应该正常工作。与调用 id 类型的对象上的方法一样,只要编译器知道该编译单元中至少有一个类,编译器就会认为找到了在 Class 对象上调用的方法。实现同名的类方法。

替代答案:

如果您确实想抑制编译器警告,例如,如果您在编译时调用任何地方都不存在的方法,那么您需要使用NSObject 的performSelector: 方法或运行时函数objc_msgSend()。编译时不会检查匹配的方法。但是,对于某些您可能希望作为参数传递的 C 类型(浮点数和某些较大的结构),编译器需要知道它们的类型。如果没有方法定义,则需要您提供信息。 performSelector: 只接受 id 类型的对象。 objc_msgSend 需要在调用之前将其转换为具有适当签名的函数(在某些情况下,用变体函数替换)。 Mike Ash 在此处很好地解释了其工作原理

Easy answer:

You don't want to do this. And if I understand your problem right, you don't need to. You're defining all the relevant methods in your Predicate class described in the link and Assertion is just forwarding to them. Including Predicate.h and making sure everything's declared in the interface should work fine. Like methods called on objects typed id, the compiler will consider methods called on a Class object to be found so long as it knows of at least one class in that compilation unit that implements a class method with the same name.

Alternative answer:

If you really want to suppress compiler warnings, for example if you're calling a method that don't exist anywhere at compile-time then you need to use either NSObject's performSelector: method or the runtime function objc_msgSend(). This won't be checked for a matching method at compile time. However, for some C types which you could plausibly want to pass as arguments (floats and certain larger structs), the compiler needs to know their type. In the absence of a method definition, it needs information from you. performSelector: works by only accepting objects of type id. objc_msgSend needs casting casted to a function with the appropriate signature before it's called (and in some cases, replacing with a variant function). Mike Ash has a good explanation of how this works here.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文