Objective-C中的类

Objective-C中的类,objective-c,macos,class,Objective C,Macos,Class,我有一个名为person的类,有两个值:age和weight。为什么我不能像这样在主函数中访问这两个值: inta=[chuck age]; int b=[卡盘重量] 最好的方法是什么?使用属性是正确的方法吗 头文件: #import <Foundation/Foundation.h> @interface person : NSObject { int age; int weight; } -(void) print;

我有一个名为person的类,有两个值:age和weight。为什么我不能像这样在主函数中访问这两个值:

inta=[chuck age];
int b=[卡盘重量]

最好的方法是什么?使用属性是正确的方法吗

头文件:

#import <Foundation/Foundation.h>
    @interface person : NSObject
    {
        int age;
        int weight;
    }
    -(void) print;
    -(void) setAge;
    -(void) setWeight;

@end
在头文件中:

@property int age;
@property int weight;

您的问题是您试图访问私有
age
weight
ivar,这两种方法无法访问

实现这一点的好方法是使用ObjC属性,但您的示例并不需要这样做

您需要创建两个方法来访问私有IVAR,分别称它们为
age
weight
,它们在类界面中应该如下所示:

- (int) age;
- (int) weight;
具体实施如下:

- (int) age{
   return age;
}

- (int) weight{
   return weight;
}
现在,在main.m中,您可以轻松访问以下所需的数据:

#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;
}
#导入
#输入“person.h”
int main(int argc,char*argV[]){
@自动释放池{
person*andrew=[[person alloc]init];
[andrew setAge];
[andrew setWeight];
NSLog(@“年龄:%d,体重:%d”,[andrew Age],[andrew Weight]);
}
返回0;
}

如果你想知道如何处理属性,请告诉我,我可以更新答案:)

你是从某种教程或书籍中学习的吗?对于学习编写OSX或iOS应用程序来说,这是一个奇怪的起点

在任何情况下,问题在于您已经将getter/setter东西与实现其他功能的方法相结合

我建议将您的
人员
类声明为:

 @interface Person : NSObject
 @property NSInteger age;
 @property NSInteger weight;
 @end
与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
也就是说,
只保存关于单个人的信息。它不执行任何类型的I/O等操作

然后,你的main.m看起来像:

#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;
}

然后从
main

调用这些方法很好,在类实现中如何设置
age
weight
,在
setAge
setWeight
方法中可能设置了错误的值。是的,您可以使用属性,但这也应该起作用,我们需要找出您的错误,而不是通过使用属性来避免:)您的
setAge
setWeight
方法为什么不带参数?您不需要传入要设置的值吗?您需要找到一个关于Objective-C的好教程,并了解属性。如何初始化
Chuck
实例,你能把
NSLog(@“扫描年龄:%d,设置年龄:%d”,v,年龄)
设置方法中扫描年龄并显示输出后?试着先确定你得到的值是正确的完美的,解决了你的问题,现在发布一个详细的答案,再给我一个:)顺便说一句:
person
应该是
person
;Objective-C课程总是以大写字母开头。请注意,如果您的目标是编写OSX或iOS应用程序,那么这是一个非常奇怪的起点。不错——学习Unix命令行goop没什么错——只是和编写应用程序所需的知识完全不同。不客气,事情可以用更好的方式来完成。我认为你似乎对Objective-C或OOP世界还不熟悉,如果是这样的话,你可以阅读apple文档和一些Objective-C教程。tutsplus.com上有非常好的初学者ObjC教程:)Objective-C中的getter从不以
get
作为前缀。这是一个改进!您仍然在暗示
setAge
setWeight
是可以的。他们不是。当然,它们不会与
setAge:
setWeight:
冲突,但这将是一个可怕的编程API@嗯,我完全同意你的看法,我并没有暗示他们是对的,但看到OP的问题,我只是说明了为什么他的代码不起作用,而不是正确的方法,我可能会改进答案,并在今晚晚些时候说明如何正确地完成:),谢谢回答,但是您不是打算将属性类型定义为
NSInteger
而不是
NSNumber
?此外,如果IVAR是自动合成的,那么它们的前缀将加下划线(当在
init
方法中引用时)。。。所以需要一个编译器来捕捉我愚蠢的错误。不是愚蠢的,只是人类。不过,这样做的一个好处是,读者倾向于填写编译器,尽管获得错误和警告的延迟要大得多。:-)
#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;
}
...
- (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: "];
}
...