在以下情况下使用objc_msgSend是否安全?

时间:2014-05-27 11:26:35

标签: objective-c objective-c-runtime

我有一个对象和一个选择器来调用所述对象。选择器将采用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,但这似乎更加麻烦,没有收获。

1 个答案:

答案 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}}版本的代码比版本版本的代码相对简单,因此我可能会使用它。我也会做一些基准来满足我的好奇心。

文档: