gpt4 book ai didi

swift - 如何安全地测试一个方法是否可以通过 NSInitation 调用

转载 作者:行者123 更新时间:2023-11-30 10:15:06 25 4
gpt4 key购买 nike

我已经使用 ObjC 运行时生成了类的方法和属性的列表,以便稍后可以使用 NSInitation 从桥中调用这些方法和属性。

问题是,对于那些运行时无法生成签名的方法,我收到错误。

例如,在 SKFieldNode 实例中调用 direction 的属性 getter 会抛出异常 NSInvalidArgumentException,我猜这是因为 vector_float3没有编码类型,其类型为''(即无字符类型)

这是测试我所描述的内容的方法:

Method method = class_getInstanceMethod([SKFieldNode class], @selector(direction));
const char *types = method_getTypeEncoding(method);
NSMethodSignature *sig = [NSMethodSignature signatureWithObjCTypes:types];
NSInvocation *inv = [NSInvocation invocationWithMethodSignature:sig];

SKFieldNode *field = [SKFieldNode node];
field.direction = (vector_float3){1,2,3};

[inv setTarget:field];
[inv setSelector:@selector(direction)]; // (*)
[inv invoke];

vector_float3 v;

[inv getReturnValue:&v];

NSLog(@"%f %f %f", v.x, v.y, v.z);

(*) "NSInvalidArgumentException", "-[NSInvocation setArgument:atIndex:]: index (1) out of bounds [-1, 0]"

如何使用内省(introspection)来判断是否可以以这种方式安全地调用方法?

我尝试测试 NSMethodSignature 返回的参数数量,但对于缺少编码类型的方法,该值是错误的,例如这两个方法将返回 2,计算目标和选择器,因此其余参数不予​​考虑。

- setDirection:(vector_float3)d1 direction:(vector_float3)d2;
- setDirection:(vector_float3)d;

我还注意到方向属性 is not available in Swift

这让我觉得这是因为同样的原因。因此,我不介意在自定义桥中放弃对这些方法的支持。

最佳答案

这是一个相当简单的检查,以确保您没有任何编码不正确的参数:

BOOL isMethodSignatureValidForSelector(NSMethodSignature *signature, SEL selector) {
// This could break if you use a unicode selector name, so please don't do that :)
const char *c_str = sel_getName(selector);
unsigned numberOfArgs = 2;

while (*c_str) {
if (*c_str == ':') {
numberOfArgs++;
};

c_str++;
}

return ([signature numberOfArguments] == numberOfArgs);
}

关于swift - 如何安全地测试一个方法是否可以通过 NSInitation 调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30554649/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com