How do I return a struct value from a runtime-defined class method under ARC?

后端 未结 2 1224
情书的邮戳
情书的邮戳 2020-12-16 21:27

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

相关标签:
2条回答
  • 2020-12-16 22:09

    If you wish to retrieve a struct from your class method, you can use an NSInvocation as follows:

    Class clazz = NSClassFromString(@"MyClass");
    SEL aSelector = NSSelectorFromString(@"testMethod");
    
    CGSize returnStruct; // Or whatever type you're retrieving
    
    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[clazz methodSignatureForSelector:aSelector]];
    
    [invocation setTarget:clazz];
    [invocation setSelector:aSelector];
    
    [invocation invoke];
    [invocation getReturnValue:&returnStruct];
    

    At the end of this, returnStruct should contain your struct value. I just tested this in an ARC-enabled application and this works fine.

    0 讨论(0)
  • 2020-12-16 22:32

    You need to cast objc_msgSend_stret to the correct function pointer type. It's defined as void objc_msgSend_stret(id, SEL, ...), which is an inappropriate type to actually call. You'll want to use something like

    CGSize size = ((CGSize(*)(id, SEL, NSString*))objc_msgSend_stret)(clazz, @selector(contentSize:), text);
    

    Here we're just casting objc_msgSend_stret to a function of type (CGSize (*)(id, SEL, NSString*)), which is the actual type of the IMP that implements +contentSize:.

    Note, we're also using @selector(contentSize:) because there's no reason to use NSSelectorFromString() for selectors known at compile-time.

    Also note that casting the function pointer is required even for regular invocations of objc_msgSend(). Even if calling objc_msgSend() directly works in your particular case, it's relying on the assumption that the varargs method invocation ABI is the same as the ABI for calling a non-varargs method, which may not be true on all platforms.

    0 讨论(0)
提交回复
热议问题