Search code examples
iosobjective-ciphoneuiviewunrecognized-selector

Unable to identify the cause of unrecognized selector error


So I'm building this iOS app. Everytime the use taps on a small square that square should change color. I've made sure that all my methods are defined. And I've changed the name of the xIndex value so that I can ENSURE that it isn't the view's .xIndex value that's the source of the crash. But no matter what I seem to do, I still seem to get:

'-[UIView xIndex]: unrecognized selector sent to instance 0x7fe06be6ce70'

Note that the above instance refers to the memory address of specificSquare. Any guesses? Been battling this for hours.

- (void)handleFunViewSquareTap:(UITapGestureRecognizer*)sender
{
    if (sender.state == UIGestureRecognizerStateEnded)
    {
        // handling code
        CGPoint locationOfTap = [sender locationInView: self.view];
        NSInteger xVIndex = floorf(locationOfTap.x / 40.f);
        NSInteger yIndex = floorf(locationOfTap.y / 40.f);

        // find the view that matches these indexes
        for(FunViewSquare *specificSquare in [self.view subviews])
        {
            if((specificSquare.xIndex == xVIndex) && (specificSquare.yIndex == yIndex))
           {
//                //specificSquare.backgroundColor = [ViewController randomColor];
           }
        }
    }
}

- (void)viewDidLoad {
    [super viewDidLoad];

        CGRect frameRect = self.view.frame;
        NSInteger xIndex, yIndex = 0;
        for( CGFloat yPosition = 0.0; yPosition < frameRect.size.height; yPosition+=40.0f )
        {
            // reset xIndex on every iteration
            xIndex = 0;
            for( CGFloat xPosition = 0.0; xPosition < frameRect.size.width; xPosition+=40.0f )
            {
                FunViewSquare *randomSquare = [[FunViewSquare alloc] initWithFrame: CGRectMake(xPosition, yPosition, 40.f, 40.0f)];

                if(randomSquare)
                {
                    randomSquare.backgroundColor = [ViewController randomColor];
                    randomSquare.xIndex = xIndex;
                    randomSquare.yIndex = yIndex;
                    [self.view addSubview: randomSquare];
                }
                xIndex++;
            }
            yIndex++;
        }

        butGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleFunViewSquareTap:)];
        if(butGestureRecognizer)
        {
            [self.view addGestureRecognizer: butGestureRecognizer];
        }

}


+ (UIColor *)randomColor
{
    UIColor *colorToReturn;

    uint32_t randomNumber = random();
    randomNumber = (randomNumber % 10); // a random number between 0 & 10

    switch(randomNumber)
    {
        case 0 :
            colorToReturn = [UIColor blueColor];
            break;
        case 1 :
            colorToReturn = [UIColor grayColor];
            break;
        case 2 :
            colorToReturn = [UIColor greenColor];
            break;
        case 3 :
            colorToReturn = [UIColor purpleColor];
            break;
        case 4 :
            colorToReturn = [UIColor redColor];
            break;
        case 5 :
            colorToReturn = [UIColor brownColor];
            break;
        case 6 :
            colorToReturn = [UIColor cyanColor];
            break;
        case 7 :
            colorToReturn = [UIColor orangeColor];
            break;
        case 8 :
            colorToReturn = [UIColor magentaColor];
            break;
        case 9 :
            colorToReturn = [UIColor whiteColor];
            break;
        default :
            colorToReturn = [UIColor blackColor];

    }
    return(colorToReturn);
}

@end

Solution

  • The problem is that you're iterating through all the subviews in self.view and not all of those views are FunViewSquare views and don't all respond to xIndex. Hence the crash.

    It seems you're assuming that the for loop will only pick out FunViewSquare objects in the subviews - this is simply not the case.

    You need to do some introspection here - rewrite your code like this:

    for(FunViewSquare *specificSquare in [self.view subviews]) {
     if ([specificSquare isKindOfClass:[FunViewSquare class]](
      if ((specificSquare.xIndex == xVIndex) && (specificSquare.yIndex == yIndex)){
               //specificSquare.backgroundColor = [ViewController randomColor];
      }
     }
    }
    

    This way you're checking to make sure that specificSquare really is a FunViewSquare object.