CaptainBear
CaptainBear

Reputation: 167

Using Custom Subclass of NS Object in 2 different IBActions

This is an objective-c problem. I have created a subclass person of NSObject with parameters 'height' and 'weight', with property and synthesize in a file called Person.h that contains both interface and implementation.

I want to import Person.h into my viewcontroller.m and create person objects and alter them using 2 IBActions.

-(IBAction)alterperson_1{

 person *bob = [person alloc]init];
 bob.height = 72;
 bob.weight = 200;
}

-(IBAction)alterperson_2{

 bob.height = 80;
 bob.weight = 250;

}

This arrangement does not work because the method alterperson_2 can't find Bob because it is a local variable to alterperson_1. My question is how and where in viewcontroller.m do I allocate Bob as a person so that his attributes can be altered by both IBActions.

I have tried allocing in viewdidload as well as in the initwith nibname methods. It did not work. I have also tried in the implementation{ } of viewcontroller.m but that doesn't work either because Bob's allocation is not a compile time constant.

Thanks!

Update With Code

So, I have the Person.h file importing properly now (thanks Robotnik), and am able to create instances of Person throughout ViewController.m -- however, my created instance *bob does not seem to retain values for its properties (see comments by NSLog statements in the code). I think this is an initialization issue, but I have no idea where to initialize. Currently, I get a warning when initializing in viewDidLoad. How do I get bob.weight to print 200 when my IBAction is called, instead of the 0 I currently get? Thanks.

// Person.h

#import <Foundation/Foundation.h>

@interface Person : NSObject{

int weight;
int height;
}

@property int weight, height;

@end

end Person.h

//Person.m


#import "Person.h"

@implementation Person

@synthesize weight, height;

@end

end Person.m

//ViewController.h

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



@interface ViewController : UIViewController{


}

@property Person *bob;

-(IBAction)persontest:(id)sender;

@end

end ViewController.h

//ViewController.m

#import "ViewController.h"

@implementation ViewController

@synthesize bob;

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    Person *bob = [[Person alloc]init]; // this causes a local declaration warning, if I remove this code, however, it still doesn't work
    bob.weight = 100;
    NSLog(@"viewDidLoad bob's weight, %i", bob.weight); // this will print 100, but only because I made the local initialization. The value is lost once the viewDidLoad Method ends.
}

-(IBAction)persontest:(id)sender{

    bob.weight = bob.weight + 100;
    NSLog(@"IBAction bob's weight %i", bob.weight); // this prints 0, probably because value is nil. How can I make it print 200?
}

- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}

@end

end ViewController.m

Upvotes: 1

Views: 159

Answers (2)

jrturton
jrturton

Reputation: 119242

You seem to be confusing declaration of a variable with allocation of a variable. You're also not using properties properly.

Declaration of a variable is done like this:

Person *bob;

That's it. If you put this line in your @interface section, or in {braces} at the top of your implementation section, then this becomes an instance variable, any time you use bob in the rest of your class it will know that you are talking to a person. So, in your viewDidLoad, you can now do this:

bob = [[Person alloc] init];

And it knows you are referring to the instance variable. In your current code, you have Person * in front of this line, which, as the compiler is telling you, is declaring a local variable with the name bob, and therefore hiding your instance variable, so you are not changing your instance variable at all, so there is no value in it later.

Looking at the nature of this question, and your comments, I would strongly advise reading some objective-c introductory texts before proceeding much further. You can ask questions here but SO is not really the place to learn a language - most answerers will assume that you know the language basics.

Upvotes: 1

Robotnik
Robotnik

Reputation: 3800

You'll need to declare Bob in your ViewController.h if you want him to be accessible across multiple methods. You can then initialise him in viewDidLoad

@interface ViewController
{
    Person *bob;
}

-(IBAction)alterperson_1;
-(IBAction)alterperson_2;
@end

You mentioned you wanted to instantiate multiple people. In that case you may want to keep multiple Person objects in an NSMutableArray or similar. This should still be declared in the ViewController.h in order to be accessible in multiple methods. You can then use the method addObject: to add people to the array. Here is an example of an array, storing strings.

NSMutableArray *stringArray = [[NSMutableArray alloc] init];

[stringArray addObject:@"Dog"];
[stringArray addObject:@"Cat"];

Upvotes: 1

Related Questions