为什么方法没有被调用

时间:2018-08-16 08:01:31

标签: objective-c class methods

我正在尝试学习如何制作类和对象以及如何在Objective-C中调用方法。我的小程序创建了一个City类的对象,允许命名该对象,设置年龄,人口并获取这些值以进行打印。但是,当我调用一个方法来设置这些值时,得到的结果为(null)和零。这是我的代码:

City.h

#import <Foundation/Foundation.h>

@interface City : NSObject

-(void) setName:(NSString *)theName Age:(int)theAge Population:(int)thePopulation;
-(void) getName;
-(void) getAge;
-(void) getPopulation;
-(void) nextDay;
@end

City.m

#import "City.h"

@implementation City
{
    NSString *name;
    int age;
    int population;
}
-(void) setName:(NSString *)theName Age:(int)theAge Population:(int)thePopulation
{
    theName = name;
    theAge = age;
    thePopulation = population;
}
-(void) getName
{
    NSLog(@"Name is %@", name);
}
-(void) getAge
{
    NSLog(@"Age is %d", age);
}
-(void) getPopulation
{
    NSLog(@"Population today is %d", population);
}

main.m

int main()
{
    City *moscow = [[City alloc] init];
    [moscow setName:@"Msk" Age:120 Population:1000];
    [moscow getName];
    [moscow getAge];
    [moscow getPopulation];
}

运行的结果是:

Name is (null)
Age is 0
Population today is 0
Program ended with exit code: 0

我在做什么错?

1 个答案:

答案 0 :(得分:2)

问题是City的实例变量从未设置。 setName:Age:Population:中的代码将实例变量(nameagepopulation)的值分配给参数变量(theName,{{1} }和theAge)。交换这些将使设置器将参数分配给实例变量:

thePopulation

也就是说,使用属性(而不是实例变量和手动获取器和设置器)并使用初始值设定项来设置初始值是更加惯用的Objective-C。经过这些更改,城市班级将如下所示:

City.h

name = theName;
age = theAge;
population = thePopulation;

City.m

NS_ASSUME_NONNULL_BEGIN

@interface City : NSObject

@property (copy)   NSString *name;
@property (assign) NSInteger age;
@property (assign) NSInteger population;

- (instancetype)initWithName:(NSString *)name
                         age:(NSInteger)age
                  population:(NSInteger)population;

@end

NS_ASSUME_NONNULL_END

有关此代码的两点注意事项:

  1. 同时复制字符串(在初始化程序和属性中),以防止传递#import "City.h" @implementation City - (instancetype)initWithName:(NSString *)name age:(NSInteger)age population:(NSInteger)population { self = [super init]; if (self) { _name = [name copy]; _age = age; _population = population; } return self; } @end 并随后对其进行突变(这也会使NSMutableString的值发生突变)对于传递不变的name的常见情况,该副本等效于“保留”。

  2. 在初始化器中分配值时使用合成的实例变量。这是为了防止子类覆盖这些属性中的任何一个,并在对象完全初始化之前运行自定义的setter方法(将其所有变量设置为其初始值)。这仅适用于初始化程序,自定义设置程序和dealloc。其他所有内容都应使用这些属性来访问和修改这些值。