函数调用的参数太多,预期为 0,有 2

ciT*_*ger 6 objective-c ios cocoapods xcode11

去年我们从 Pixate 迁移到了 StylingKit

https://github.com/StylingKit/StylingKit是 Pixate 的一个分支,据我所知仍在开发中。

然而,随着 XCode 11 的发布,我们现在遇到了问题,在 pior 版本中它运行良好,但现在无法编译。

    void* callSuper0(id self, Class superClass, SEL _cmd)
    {
        struct objc_super super;
        super.receiver = (__bridge void *)self;
        super.class = superClass != NULL ? superClass : class_getSuperclass(object_getClass(self));
        return objc_msgSendSuper(&super, preprocessSEL(_cmd));
    }

Run Code Online (Sandbox Code Playgroud)
return objc_msgSendSuper(&super, preprocessSEL(_cmd));
Run Code Online (Sandbox Code Playgroud)

抛出错误“函数调用的参数太多,预期为 0,有 2”

我尝试更改一些构建设置,如函数调用的参数过多,预​​期为 0,有 3 个特别是“启用对 objc_msgSend 调用的严格检查为 NO”,但它没有帮助。

任何帮助,将不胜感激。

CRD*_*CRD 4

注意:下面的代码尚未执行,因为它只是一个片段,但它是由 Xcode 10 和 11 编译的。可能存在错误或其他问题。

\n\n

在 Xcode 中右键单击objc_superobjc_msgSendSuper选择“跳转到定义”,这将打开包含定义的系统文件。这将表明两件事:

\n\n
    \n
  1. objc_super自从编写代码以来,字段名称和类型都发生了变化,其中一些记录在注释中。
  2. \n
  3. 原型objc_msgSendSuper也变成了刚才void objc_msgSendSuper(void),之前的原型也还在id _Nullable\nobjc_msgSendSuper(struct objc_super * _Nonnull super, SEL _Nonnull op, ...)。使用以前的原型,可以在代码中调用此函数而无需进行强制转换,而使用这个新原型则需要进行强制转换。
  4. \n
\n\n

对代码进行指示的更改会得到:

\n\n
// A typedef for objc_msgSendSuper which takes only the required (first two) arguments\ntypedef void *(*NoAdditionalArgMsgSendSuper)(struct objc_super *super_class, SEL selector);\n\nvoid* callSuper0(id self, Class superClass, SEL _cmd)\n{\n   struct objc_super super;\n   // .receiver is now defined as "__unsafe_unretained _Nonnull id" so no bridge cast required\n   super.receiver = self;\n   // .super_class is new name for .class\n   super.super_class = superClass != NULL ? superClass : class_getSuperclass(object_getClass(self));\n   // cast objc_msgSendSuper to the correct type and then call\n   return ((NoAdditionalArgMsgSendSuper)objc_msgSendSuper)(&super, preprocessSEL(_cmd));\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

华泰

\n\n

附录

\n\n

根据您的评论和代码帖子作为另一个答案。

\n\n

在你的代码中你写:

\n\n
void* (*objc_msgSendSuperTyped)(id self, SEL _cmd) = (void*)objc_msgSendSuper;\nreturn objc_msgSendSuperTyped((id) &super, preprocessSEL(_cmd));\n
Run Code Online (Sandbox Code Playgroud)\n\n

制作函数指针的类型化副本,而不是像我们之前的代码那样仅仅在使用时进行强制转换,这样就可以了。但是,当您尝试将非保留类型(&super- 结构指针)转换为保留类型(id) \xe2\x80\x93\xc2\xa0 时,您的代码应该从 Xcode 中产生错误,这需要桥接转换。

\n\n

这里的解决方案是给出objc_msgSendSuperTyped正确的类型,它的第一个参数应该是结构指针:

\n\n
void* (*objc_msgSendSuperTyped)(struct objc_super *self, SEL _cmd) = (void*)objc_msgSendSuper;\nreturn objc_msgSendSuperTyped(&super, preprocessSEL(_cmd));\n
Run Code Online (Sandbox Code Playgroud)\n\n

从你的评论来看:

\n\n
\n

我必须将 super.super_class 更改为 super.class 才能正常工作,它现在会引发其他不相关的错误。

\n
\n\n

这表明你有一些不寻常的设置,在声明中objc_super我们发现:

\n\n
#if !defined(__cplusplus)  &&  !__OBJC2__\n   /* For compatibility with old objc-runtime.h header */\n   __unsafe_unretained _Nonnull Class class;\n#else\n   __unsafe_unretained _Nonnull Class super_class;\n#endif\n
Run Code Online (Sandbox Code Playgroud)\n\n

__OBJC2__在 Xcode 11(以及许多早期版本)中默认为.m.mm文件定义,仅为文件__cplusplus定义.mm。所以条件!defined(__cplusplus) && !__OBJC2__false,因此该字段被命名为super_class......

\n\n

您可能希望确定为什么__OBJC2__显然没有为您尝试转换的源定义...

\n