无法将objc_msgsend安全地强制转换为可变长度参数函数
假设我在运行时得到一个对象和它的一个选择器,我打算安全地调用它,所以我定义了无法将objc_msgsend安全地强制转换为可变长度参数函数,c,objective-c,objective-c-runtime,C,Objective C,Objective C Runtime,假设我在运行时得到一个对象和它的一个选择器,我打算安全地调用它,所以我定义了 #define objc_msgsend_va ((void (*)(id, SEL, ...))objc_msgsend) #define Call_object(obj, sel, ...) objc_msgsend_va(obj, sel, ## __VA_ARGS__) 我是否可以用call_object宏安全地替换任何方法调用,否则可能导致某种崩溃 这是为了定义一个宏来在iOS设备上运行任意运行时方法,我
#define objc_msgsend_va ((void (*)(id, SEL, ...))objc_msgsend)
#define Call_object(obj, sel, ...) objc_msgsend_va(obj, sel, ## __VA_ARGS__)
我是否可以用call_object宏安全地替换任何方法调用,否则可能导致某种崩溃
这是为了定义一个宏来在iOS设备上运行任意运行时方法,我无法显式强制转换来更正每个方法的函数类型,所以我使用了可变长度参数
主要考虑的是这样使用宏的安全性。底线:
不,这绝对不安全。它在许多常见情况下都能工作,但va_args与直接向函数传递参数不同
请,请,请,使用NSInvocation
它可以为您解决99%的问题,同时更安全。它可能无法解决某些边缘情况(例如,参数列表中的SSE/AVX向量),但它将比您可能一起解决的问题有很大的进步
让我们按体系结构对此进行分解,看看这可能在哪里起作用
普遍的
这些问题将无处不在,没有真正的解决办法
short
s和char
s。它们也都会被放大,在经过时会造成很多痛苦和痛苦。从技术上讲(与浮点数不同,浮点数有时在特殊的FPU寄存器中传递),对于整数类型,可以通过将它们包装在单个元素结构中来解决这一问题。这将阻止他们晋升。不过,请不要这样做大多数函数调用都是完全通过寄存器执行的,所以我们之前所有的担心都还在这里。现在有新的浮点FPU寄存器需要处理,但如果你已经做到这一点,没有什么是无法克服的。感谢你的回答,NSInvocation与va_列表集成,在定义的C_类型的帮助下,确实解决了我的大部分问题,最后一个可能是,我不能用va_args将任意大小的类型出列,GNU澄清它的实现可能会随着时间的推移而改变。对于这些类型的函数,我只返回nil,现在它的工作方式类似于带有KVC包装特性的objc_msgSend。