0

I am trying to use invocation to callback a UIView in Objective C and toggle its hidden property. The message must be sent to a custom view in a dedicated class SquareView.

For demonstration purposes my invokerMethod will be called from a UIButton. The appropriate place for this and the SquareView property would seem to be the UIViewController. But I can’t tell whether invocation is meant to return a value and my sample code gives the following error

+[NSInvocation _invocationWithMethodSignature:frame:]: method signature argument cannot be nil'

Can someone please point out what I have got wrong. The examples of NSInvocation I’ve looked at here here and here have so far not shed any light on this. And this link is dead.


EDIT

This may be a duplicate question but the answer did not fix my problem. But I found another question on invocation with answers that helped produce a simpler version of what I am trying to do, with a slightly different problem related to the one here in this post.


Here is my code so far

ViewController.h

#import <UIKit/UIKit.h>
#import "SquareView.h"

@interface ViewController : UIViewController

@property (nonatomic, weak) UIView* square;

@end

ViewController.m

- (void)viewDidLoad {
    [super viewDidLoad];

    SquareView *square = [[SquareView alloc] initWithFrame:CGRectMake(60, 60, 100, 100)];
    [self.view addSubview:square];               // draw once only

    [self.view addSubview:[self button:CGRectMake(120, 230, 100, 50)]];


    SEL selector                = @selector(invokerMethod:);
    BOOL toggle;

    UIView *target              = _square;

    NSInvocation *invocation    = [NSInvocation invocationWithMethodSignature:[target methodSignatureForSelector:selector]];
    invocation.selector         = selector;
    invocation.target           = target;

    [invocation setArgument:&toggle atIndex:2];
    [invocation invoke];

    __weak id returnValue       = nil;
    [invocation getReturnValue:&returnValue];
}

Here is the invoker method …

- (id)invokerMethod:(NSInteger)tag
{
    NSLog(@"toggle view each time”);
    if (_square) 
    {
        if (_square.hidden)
        {
            [_square setHidden:NO];
        }
        else
        {
            [_square setHidden:YES];
        }
    }
    return nil;
}

… and here is the button method …

- (UIButton *)button:(CGRect)box
{
    UIButton *tap           = [[UIButton alloc] initWithFrame:box];
    tap.backgroundColor     = [UIColor lightGrayColor];
    [tap setTitle:@“toggle" forState:UIControlStateNormal];
    [tap addTarget:self action:@selector(invokerMethod) forControlEvents:UIControlEventTouchUpInside];
    return tap;
}

… and here is the view that gets toggled.

SquareView.h

#import <UIKit/UIKit.h>

@interface SquareView : UIView

@end

SquareView.m

#import "SquareView.h"

@implementation SquareView

- (id)initWithFrame:(CGRect)frame
{
    self                        = [super initWithFrame:frame];

    if (self)
    {
        UIView *square          = [[UIView alloc] initWithFrame:frame];
        square.backgroundColor  = [UIColor redColor];
        [self addSubview:square];
    }
    return self;
}

@end
Greg
  • 1,750
  • 2
  • 29
  • 56
  • Possible duplicate of https://stackoverflow.com/questions/20039600/why-does-this-nsinvocation-raise-an-exception – matt Aug 07 '18 at 01:37
  • matt, possibly but the answer there so far hasn't change my problem. I'm now looking at messaging rather than invocation, and in particular [http://www.apeth.com/iOSBook/ch03.html#_messages_as_data_type] – Greg Aug 07 '18 at 03:05
  • Well I don't see how _that's_ going to help. :) – matt Aug 07 '18 at 03:12

0 Answers0