这是问题的有意“分支”: Obj-C introspection: How can a method reference its own selector?
我需要做与 OP 完全相同的事情,但是虽然他不需要传递任何参数,但我确实这样做了。
我已经有一种方法可以调用具有多个未知参数的方法(NSInvocation)。我有一些方便的方法可以为我做这件事,就像在这个问题中一样。但是,必须为每个需要这样做的类中的每个方法重复工作,这会导致维护问题,并且当错误的参数(或以错误的顺序)传递给便捷方法时会出现地狱般的调试。
这本身是一个相对较小的问题,但我已经努力了两年,并希望解决这个问题。通过使用单行宏(如@Michael57)来调用我的便捷方法,自动检查选择器(使用 _cmd)和参数(使用?)并按照我的意愿调用便捷方法。
请注意,这适用于具有固定参数列表而不是可变参数的方法。所以我不确定 va_args 方法是否适用于检查参数。
因此,无论是从代码管理的角度来看,还是纯粹出于技术上的好奇心(如果选择器存在 _cmd,那么参数必须有一些东西?)我想知道如何内省标准的 Obj-C 方法参数。
我希望这是我所缺少的非常明显的东西。谢谢您的帮助!
编辑:一些示例代码:我尝试做的基本目的是始终在单个线程中运行在某个实例上调用的方法。为此,我在 NSObject 类别中有一个类似的便捷方法:
- (void)performSelectorInBackground:(SEL)aSelector waitUntilDone:(BOOL)waitUntilDone withArgumentLocations:(void *)firstArg,...;
它在专门映射到该实例的特定后台线程中的目标对象上运行被调用的选择器。所有这些只是为了避免一些否则会发生的粘性同步问题。
也许这一切一开始都是笨拙的,但我已经过去了。这段代码集成在太多地方。:)
“withArgumentLocations”可变参数列表是一个指针位置列表,它可以接受标量值和常规 Obj-C 对象,从而使在后台调用具有可变数量和类型的参数的选择器的常规任务变得简单 1-线事。
无论如何,一个实际的用例如下:
- (void)loginRequestWithUsername:(NSString *)username andPassword:(NSString *)password {
if(![self isInBackgroundThread])
{
[self performSelectorInBackground:@selector(loginRequestWithUsername:andPassword:) waitUntilDone:NO withArgumentLocations:&username, &password, nil];
return;
}
[self isInBackgroundThread]
是另一种方便的方法,它检查当前执行线程是否是此实例的“分配”线程。
所以这种方法对于单个方法调用效果很好,但现在我想将它扩展到一个类中的所有方法。当“argumentLocations”未正确替换或未按正确顺序等时,这有时会导致问题,从而导致地狱般的调试。
这就是为什么我想用一个小宏替换上面的代码块,我可以简单地将它粘贴到每个方法中来实现我需要的。
这就是为什么这个宏应该能够查询它自己的选择器(_cmd)和参数(使用?)并将它们传递给我的performSelectorInBackground:waitUntilDone:withArgumentLocations:
方法。