Pangu
Pangu

Reputation: 3819

Why is Xcode complaining about "unrecognized selector sent to instance" error?

let me start off by saying I know what the error means. It's basically saying the Selector method was invoked on an object that doesn't have that method.

Anyways, here's my Tile.h header file:

#import <Foundation/Foundation.h>
#import "Weapon.h"
#import "Armor.h"


@interface Tile : NSObject

@property (strong, nonatomic) NSString *story;
@property (strong, nonatomic) Weapon *weapon;
@property (strong, nonatomic) Armor *armor;
@property (nonatomic) int healthEffect;

@end

Here is my Factory.h header file:

#import <Foundation/Foundation.h>


@interface Factory : NSObject

- (NSArray *)tiles;

@end

And here is my Factory.m file:

#import "Factory.h"
#import "Tile.h"

@implementation Factory

- (NSArray *) tiles
{
    Tile *tile7 = [ [Tile alloc] init];
    tile7.story = @"blah blah";
    tile7.healthEffect = 8;
}
@end

Some code is excluded in the Factory.m file because they're trivial but if I try to compile and run, I get this error:

2014-10-29 17:26:27.944 Pirate Adventure[718:15257]
-[Tile setHealthEffect:]: unrecognized selector sent to instance 0x7b03b8e0
2014-10-29 17:26:27.946 Pirate Adventure[718:15257] *** Terminating app due to uncaught 
exception 'NSInvalidArgumentException', reason: '-[Tile setHealthEffect:]: unrecognized 
selector sent to instance 0x7b03b8e0'

It's complaining when I try to set tile7.healthEffect = 8;

I don't even understand why it's complaining about the setHealthEffect method, I don't even have that define in my Tile.h header file. Also, healthEffect is just a property of the tile object, so I should be able to set it to whatever integer value I want without having to define a method to set the value right?

I'm confused.

Thanks!

Added Tile.m file:

#import "Tile.h"

@implementation Tile

@synthesize healthEffect = _healthEffect;

@end

Upvotes: 1

Views: 877

Answers (2)

Rob
Rob

Reputation: 438307

The problem does not rest in the code you've shared with us thus far. For some reason, your setter simply hasn't been synthesized. Please share your Tile implementation. For example, you'd get this sort of error if either:

  • the healthEffect was a property declared in a protocol used by Tile class; or

  • your Tile implementation had a line that explicitly declared that the property shouldn't be synthesized:

    @dynamic heathEffect;
    

You go on to ask:

For some reason, your setter simply hasn't been synthesized.

I don't even understand why it's complaining about the setHealthEffect method, I don't even have that define in my Tile.h header file.

As Klaus pointed out, using tiles.healthEffect = ... is equivalent to calling setHealthEffect.

Also, healthEffect is just a property of the tile object, so I should be able to set it to whatever integer value I want without having to define a method to set the value right?

Correct. This setHealthEffect method should have been synthesized for you automatically. Since Xcode version 4.4, these setters have been synthesized for us. There's nothing in your question to suggest why this setter was not synthesized for you in this case.

Upvotes: 0

Klaus Thul
Klaus Thul

Reputation: 685

The line

tile7.healthEffect = 8;

is just syntactic shugar for

[tile7 setHealthEffect: 8];

If you have a @property declaration in a class, the compiler will normally automatically generate a setter setHealthEffect and a getter healthEffect as well as an instance variable _healthEffect for you unless you create them yourself.

I suspect your problem is in Tile.m. Can you share this as well?

Upvotes: 1

Related Questions