I have a class method returning a CGSize
and I'd like to call it via the Objective-C runtime functions because I'm given the class and method names as string values.
I'm compiling with ARC flags in XCode 4.2.
Method signature:
+(CGSize)contentSize:(NSString *)text;
The first thing I tried was to invoke it with objc_msgSend
like this:
Class clazz = NSClassFromString(@"someClassName);
SEL method = NSSelectorFromString(@"contentSize:");
id result = objc_msgSend(clazz, method, text);
This crashed with "EXC_BAD_ACCESS" and without a stack trace. I used this first because the documentation for objc_msgSend
says,
When it encounters a method call, the compiler generates a call to one of the functions
objc_msgSend
,objc_msgSend_stret
,objc_msgSendSuper
, orobjc_msgSendSuper_stret
. [...] Methods that have data structures as return values are sent usingobjc_msgSendSuper_stret
andobjc_msgSend_stret
.
Next, I used objc_msgSend_stret
like this:
Class clazz = NSClassFromString(@"someClassName);
SEL method = NSSelectorFromString(@"contentSize:");
CGSize size = CGSizeMake(0, 0);
objc_msgSend_stret(&size, clazz, method, text);
Using the above signature gives me the following two compiler errors and two warnings:
error: Automatic Reference Counting Issue: Implicit conversion of a non-Objective-C pointer type 'CGSize *' (aka 'struct CGSize *') to 'id' is disallowed with ARC
warning: Semantic Issue: Incompatible pointer types passing 'CGSize *' (aka 'struct CGSize *') to parameter of type 'id'
error: Automatic Reference Counting Issue: Implicit conversion of an Objective-C pointer to 'SEL' is disallowed with ARC
warning: Semantic Issue: Incompatible pointer types passing '__unsafe_unretained Class' to parameter of type 'SEL'
If I look at the declaration of the method, it is:
OBJC_EXPORT void objc_msgSend_stret(id self, SEL op, ...)
__OSX_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0);
which is identical to objc_msgSend
:
OBJC_EXPORT id objc_msgSend(id self, SEL op, ...)
__OSX_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0);
This explains the compiler errors to me but what do I use at the run-time level to invoke a class and its static method at run-time and return a struct value?