Reputation: 651
I have a class named person, with two values: age and weight.Why can't I access these two values in the main function like this:
int a=[chuck age];
int b=[chuck weight];
What is the best way to do that? Using properties is the correct way?
Header file:
#import <Foundation/Foundation.h>
@interface person : NSObject
{
int age;
int weight;
}
-(void) print;
-(void) setAge;
-(void) setWeight;
@end
Implementation file:
#import "person.h"
@implementation person
-(void) print
{
printf("Your age is %d and your weight is %d.", age, weight);
}
-(void) setAge
{
printf("Write age: ");
int v;
scanf("%d", &v);
age=v;
}
-(void) setWeight
{
printf("Write weight: ");
int g;
scanf("%d", &g);
weight=g;
}
@end
Upvotes: 0
Views: 165
Reputation: 3239
Your problem is You're trying to access private age
and weight
ivars, which aren't accessible this way.
The good way to do this is to use ObjC properties, but this is not required for your example.
You need to create two methods to access the private ivars, call them age
and weight
, they should look like this in the class interface:
- (int) age;
- (int) weight;
and the implementation is:
- (int) age{
return age;
}
- (int) weight{
return weight;
}
Now in your main.m you can easily access the data needed like this:
#import <Foundation/Foundation.h>
#import "person.h"
int main(int argc, char *argV[]) {
@autoreleasepool {
person *andrew = [[person alloc]init];
[andrew setAge];
[andrew setWeight];
NSLog(@"Age:%d, Weight:%d",[andrew age], [andrew weight]);
}
return 0;
}
If you want to know how it's done with properties please let me know and I can update the answer :)
Upvotes: 2
Reputation: 162712
Are you working from some kind of a tutorial or book? That is an odd place to start for learning to write OS X or iOS apps.
In any case, the issue is that you've colluded getter/setter stuff with methods that implement other functionality.
I would suggest that your Person
class be declared as:
@interface Person : NSObject
@property NSInteger age;
@property NSInteger weight;
@end
With Person.m:
@implementation Person
- (id) init {
self = [super init];
if (self) {
// preposterous initial values so we know if they weren't set.
_age = -1;
_weight = -1;
}
return self;
}
@end
That is, a Person
only holds information about a single person. It does not do any kind of I/O, etc...
Then, your main.m would look something like:
#import <Foundation/Foundation.h>
#import "Person.h"
NSInteger ScanIntegerWithPrompt(NSString *prompt) {
printf("%s: ", [prompt UTF8String]);
int v;
scanf("%d", &v);
return (NSInteger) v;
}
int main(...) {
@autoreleasepool {
Person *p = [[Person alloc] init];
p.age = ScanIntegerWithPrompt(@"Enter age:");
p.weight = ScanIntegerWithPrompt(@"Enter weight:");
printf("Your age is %d and your weight is %d", p.age, p.weight);
}
return 0;
}
Structuring the code this way separates the Model -- the data container -- from the Control layer. There isn't much of a View layer here.
If you really wanted to keep the I/O / parse logic with the Person
object, then add something like this to the Person object:
...
- (NSNumber)readIntegerWithPrompt:(NSString*)prompt
{
... same code as function above ...
}
- (void)readAgeFromStandardInput
{
self.age = [self readIntegerWithPrompt:@"Enter age: "];
}
- (void)readWeightFromStandardInput
{
self.weight = [self readIntegerWithPrompt:@"Enter weight: "];
}
...
Then you'd call those methods from your main
.
Upvotes: 8