WorkForPizza
WorkForPizza

Reputation: 15

Use of undeclared identifier in Objective C

I'm very new to Objective C and am having trouble with some very basic things.
In AppDelegate.m, I'm getting the following errors:

Use of undeclared identifier 'health'
Use of undeclared identifier 'attack'

Code (respectively):

[Troll setValue:100 forKeyPath:health];
[Troll setValue:10 forKeyPath:attack];

I'm not really sure how to declare the identifiers.

AppDelegate.m

#import "AppDelegate.h"

@implementation AppDelegate


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

{

    NSObject *Troll = [[NSNumber alloc]init];

    [Troll setValue:100 forKeyPath:health];

    [Troll setValue:10 forKeyPath:attack];

    return YES;

}

@end

AppDelegate.h

#import `<UIKit/UIKit.h>`

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;

@end

@interface Troll : NSObject {

    NSNumber *health;

    NSNumber *attack;

}

@end

Upvotes: 0

Views: 3427

Answers (3)

AW101
AW101

Reputation: 1650

Although you are defining a class called Troll with a 'health' and 'attack', you aren't instantiating one. You probably want one of the following in your application didFinishLaunchingWithOptions:

Troll *troll = [[Troll alloc]init];
troll.health = [NSNumber numberWithInt:100];
troll.attack = [NSNumber numberWithInt:10];

OR

Troll *troll = [[Troll alloc]init];
[troll setHealth:[NSNumber numberWithInt:100]];
[troll setAttack:[NSNumber numberWithInt:10]];

These two are equivalent.

Upvotes: -1

The first thing to say is that you are not instantiating a Troll object, but a NSNumber... why? You would have to do Troll *troll = [[[Troll alloc] init] autorelease];

The way to set and get attributes from classes uses to be by declaring properties on the class. This way the compiler will manage the memory for you (retains and releases). Another way would be accessing directly your ivars.

However, if you want to use the setValue:forKeyPath: you have to use a NSString for the second paremeter, which is the name of the variable.

@interface Troll : NSObject
{
    NSNumber *_health;
    NSNumber *_attack;
}

@property (nonatomic, retain) NSNumber *health;
@property (nonatomic, retain) NSNumber *attack;

@end


@implementation Troll

@synthesize health = _health;
@synthesize attack = _attack;

- (void)dealloc
{
    [_health release];
    [_attack release];
    [super release];
}


- (void)customMethod
{
    //using properties
    [self setHealth:[NSNumber numberWithInteger:100];
    [self setAttack:[NSNumber numberWithInteger:5];

    //accessing ivars directly - remember to release old values
    [_health release];
    _health = [[NSNumber numberWithInteger:100] retain];
    [_attack release];
    _attack = [[NSNumber numberWithInteger:5] retain];
}

@end

Good luck!

Upvotes: 1

user529758
user529758

Reputation:

Keys are strings, and not something else (like dangling syntactic garbage). Furthermore, '100' and '10' are not objects. Even after this, you don't want to set the properties of the class itself but of its instances. Try

[troll setValue:[NSNumber numberWithInt:100] forKeyPath:@"health"];
[troll setValue:[NSNumber numberWithInt:10] forKeyPath:@"attack"];

instead.

Upvotes: 4

Related Questions