Objective c 检查ObjC选择器(SEL)上是否有参数

Objective c 检查ObjC选择器(SEL)上是否有参数,objective-c,selector,introspection,nsinvocation,Objective C,Selector,Introspection,Nsinvocation,就像ui按钮一样,我可以: [button addTarget:target forSelector:@selector(action)] 或: 在第二种情况下,按钮的操作将有一个发送器(即按钮本身),我如何确定给定的选择器是否有参数,以便我可以向其传递某些信息?作为第一次传递,我将使用。如果因为某种原因给你带来了问题,我会使用 Jeffery是对的(很多动态ObjC都是通过这种方式处理的,而不是深入到NSMethodSignature的内部,这会为您提供更精确的信息)。但同样,你总是可以传递

就像
ui按钮
一样,我可以:

[button addTarget:target forSelector:@selector(action)]
或:


在第二种情况下,按钮的操作将有一个发送器(即按钮本身),我如何确定给定的选择器是否有参数,以便我可以向其传递某些信息?

作为第一次传递,我将使用。如果因为某种原因给你带来了问题,我会使用

Jeffery是对的(很多动态ObjC都是通过这种方式处理的,而不是深入到
NSMethodSignature
的内部,这会为您提供更精确的信息)。但同样,你总是可以传递一些东西。我知道这听起来很疯狂,但在ObjC中传递太多东西实际上并不是问题

@interface MyObject: NSObject
- (void)something;
@end

...

MyObject *object = [MyObject new];
[object performSelector:@selector(something) withObject:@"thing"];
很好。什么!?!?是 啊这就是按钮示例的实际工作方式。在
iAction
中设置断点,然后查看调用者:

0x108b21d2c <+58>: movq   0x1400a1d(%rip), %rsi     ; "performSelector:withObject:withObject:"
0x108b21d33 <+65>: movq   %rbx, %rdi
0x108b21d36 <+68>: movq   %r12, %rdx
0x108b21d39 <+71>: movq   %r15, %rcx
0x108b21d3c <+74>: movq   %r14, %r8
0x108b21d3f <+77>: callq  *0x10ac7f3(%rip)          ; (void *)0x0000000108019ac0: objc_msgSend

是的,你可以撕开选择器,找出发送什么或不发送什么,但在Cocoa中执行此操作的典型方法是设置好一切,让接收者忽略它。

这是C的行为。这是“疯狂”吗?@Aminegm Awad一点也不疯狂。对于那些不熟悉类C语言的低级调用约定的人来说,这很可能令人惊讶(这在语言中并不普遍适用)。当然,同样的方法也可以(并且是)用于间接调用C函数指针。@Aminegm Awad:我认为这实际上不是在C中定义的。我认为,尝试使用具有不同签名的函数指针调用函数(即使用带参数的函数指针类型调用没有参数的函数)是正确的在C中是技术上未定义的行为。他们在这里所做的只是在苹果架构(可能还有大多数其他架构)上工作。@newact我没有用标准检查它。但该实现没有原型。在这种情况下,如果我错了,请纠正我,传递太多args是不正确的。这是因为,如果第一个参数到函数params的传递方式取决于params的总数,则它只能中断。但这根本无法工作,因为没有原型,参数的数量是未知的。我认为,RTE只是从定义的行为中获益。但也许我错了。@Aminegm Awad:我不知道你说的“实现没有原型”是什么意思
@interface MyObject: NSObject
- (void)something;
@end

...

MyObject *object = [MyObject new];
[object performSelector:@selector(something) withObject:@"thing"];
0x108b21d2c <+58>: movq   0x1400a1d(%rip), %rsi     ; "performSelector:withObject:withObject:"
0x108b21d33 <+65>: movq   %rbx, %rdi
0x108b21d36 <+68>: movq   %r12, %rdx
0x108b21d39 <+71>: movq   %r15, %rcx
0x108b21d3c <+74>: movq   %r14, %r8
0x108b21d3f <+77>: callq  *0x10ac7f3(%rip)          ; (void *)0x0000000108019ac0: objc_msgSend
(lldb) po $rdx
<UIButton: 0x7f8071a126f0; frame = (164 318; 46 30); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x608000223140>>

(lldb) po $rcx
<UITouchesEvent: 0x6180001068a0> timestamp: 1.06651e+06 touches: {(
    <UITouch: 0x7f8070500e20> phase: Ended tap count: 1 force: 0.000 window: <UIWindow: 0x7f8071a10890; frame = (0 0; 414 736); autoresize = W+H; gestureRecognizers = <NSArray: 0x60800026dbc0>; layer = <UIWindowLayer: 0x608000222800>> view: <UIButton: 0x7f8071a126f0; frame = (164 318; 46 30); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x608000223140>> location in window: {205, 335} previous location in window: {205, 335} location in view: {41, 17} previous location in view: {41, 17}
)}