【发布时间】:2015-05-31 06:45:51
【问题描述】:
我已经使用 ObjC 运行时生成了一个类的方法和属性列表,以便以后可以使用 NSInvocation 从桥接器调用这些方法和属性。
问题在于,对于那些运行时无法生成签名的方法,我遇到了错误。
例如在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:]: 索引 (1) 超出范围 [-1, 0]"
如何使用自省来判断一个方法是否可以安全地以这种方式调用?
我尝试测试NSMethodSignature 返回的参数数量,但是对于缺少编码类型的方法,该值是错误的,例如这两个方法将返回 2,计算目标和选择器,因此剩余的参数是不考虑。
- setDirection:(vector_float3)d1 direction:(vector_float3)d2;
- setDirection:(vector_float3)d;
我还注意到方向属性is not available in Swift
这让我觉得是因为同样的原因。所以我不介意在自定义桥中放弃对这些方法的支持。
【问题讨论】:
标签: swift cocoa objective-c-runtime scripting-bridge