Objective-C中的类
我有一个名为person的类,有两个值:age和weight。为什么我不能像这样在主函数中访问这两个值: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;
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: "];
}
...