代码之家  ›  专栏  ›  技术社区  ›  rafulin

为什么不调用方法

  •  0
  • rafulin  · 技术社区  · 6 年前

    我正在尝试学习如何在Objective-C中创建类和对象以及如何调用方法。我的小程序创建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
    

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

    主要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 回复  |  直到 6 年前
        1
  •  2
  •   David Rönnqvist    6 年前

    问题是 City 永远都不可能。密码输入 setName:Age:Population: 分配实例变量的值( name , age ,和 population theName , theAge ,和 thePopulation

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

    也就是说,使用properties实例变量头、手动getter和setters以及使用初始值设定项来设置初始值是更为惯用的Objective-C。有了这些变化,城市阶层看起来会像这样:

    城市h

    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
    

    #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
    

    关于此代码,需要注意两件事:

    1. 字符串在初始化器和属性中都被复制,以防止 NSMutableString 也。对于不可变的 NSString 如果通过,则副本相当于“保留”。

    2. 在初始值设定项中赋值时使用合成实例变量。这是为了防止子类重写这些属性,并在对象完全初始化之前运行自定义setter方法(将其所有变量设置为其初始值)。这只适用于初始值设定项、自定义设置项和解除锁定。其他所有内容都应该使用属性来访问和修改这些值。