private void callMethod(Object o, String selectorName, NSInvocation invocation) {
try {
Method method = methodForSelector(selectorName);
NSMethodSignature nsMethodSignature = invocation.methodSignature();
String typeToReturnToObjC = nsMethodSignature.methodReturnType();
if (nsMethodSignature.numberOfArguments() - method.getParameterTypes().length != 2)
throw new NoSuchMethodException(String.format(
"Number of arguments mismatch for invocation of selector %s (%s arguments supplied), method %s expects %s",
selectorName, nsMethodSignature.numberOfArguments(), method.getName(), method.getParameterTypes().length));
if (typeToReturnToObjC.equals("v") && method.getReturnType() != void.class)
throw new NoSuchMethodException(String.format(
"Selector %s expects void return, but method %s returns %s",
selectorName, method.getName(), method.getReturnType()));
if (method.getReturnType() == void.class && !(typeToReturnToObjC.equals("v")))
throw new NoSuchMethodException(String.format(
"Method %s returns void, but selector %s expects %s",
method.getName(), selectorName, typeToReturnToObjC));
Object[] marshalledArgs = argsForFrom(method, invocation, nsMethodSignature);
method.setAccessible(true);
Object result = method.invoke(o, marshalledArgs);
putResultIntoInvocation(invocation, typeToReturnToObjC, result);
} catch (InvocationTargetException e) {
logging.error("Exception calling method for selector " + selectorName, e);
throw new RococoaException("Exception calling method for selector " + selectorName, e.getCause());
} catch (Exception e) {
logging.error("Exception calling method for selector " + selectorName, e);
throw new RococoaException("Exception calling method for selector " + selectorName, e);
}
}