我有一个对象和一个选择器来调用所述对象。选择器将采用4种形式中的一种(建模类似于目标 - 动作模式):
-(void)selectorWithZeroArguments;
-(void)selectorWithObject:(id)object;
-(void)selectorWithObject:(id)object dictionary:(NSDictionary *)dict;
-(void)selectorWithObject:(id)object dictionary:(NSDictionary *)dict string:(NSString *)string;
```
目前我有switch
如下:
switch ([[object methodSignatureForSelector:selector] numberOfArguments]) {
case 2:
objc_msgSend(object, selector);
break;
case 3:
objc_msgSend(object, selector, otherObject);
break;
case 4:
objc_msgSend(object, selector, otherObject, dictionary);
break;
case 5:
objc_msgSend(object, selector, otherObject, dictionary, string);
break;
}
```
删除switch语句并仅使用objc_msgSend(object, selector, otherObject, dictionary, string)
是否安全?我的测试表明,向objc_msgSend
发送其他参数是无害的,我找不到支持或反驳这一点的文档。
此外,有没有更好的方法来解决这个问题?我知道我可以使用NSInvocation
,但这似乎更加麻烦,没有收获。
答案 0 :(得分:2)
因此,在developer.apple.com上搜索更多内容以及Objective-C邮件列表中的一些帮助,我得出结论,用objc_msgSend
调用其他参数是不明智的。但是,如果将objc_msgSend
强制转换为正确的函数原型,则可以使用objc_msgSend(object, selector, otherObject)
。上面的一个例子:
((void(*)(id, SEL, id))objc_msgSend)(object, selector, otherObject);
应该被视为:
NSInvocation
此转换将允许编译器确保正确构造堆栈帧。
{{1}}版本的代码比版本版本的代码相对简单,因此我可能会使用它。我也会做一些基准来满足我的好奇心。
文档: