【问题标题】:Why method is not getting called为什么方法没有被调用
【发布时间】:2019-01-23 03:12:33
【问题描述】:

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

城市.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

城市.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

我做错了什么?

【问题讨论】:

  • 这看起来像是来自一个非常古老的教程的代码。现代的 ObjC 看起来不是这样的;一切都是@propertys,getter 方法永远不会以get 为前缀。同样,实例变量也很少被声明了。

标签: objective-c class methods


【解决方案1】:

问题是City 的实例变量从未设置。 setName:Age:Population: 中的代码将实例变量(nameagepopulation)的值分配给参数变量(theNametheAgethePopulation)。交换这些将导致 setter 将参数分配给实例变量:

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

也就是说,Objective-C 更习惯使用属性——而不是实例变量和手动 getter 和 setter——并使用初始化程序来设置初始值。通过这些更改,City 类将如下所示:

城市.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

城市.m

#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 被传递并随后被改变(这也会改变 name 的值。对于常见的如果传递了不可变的NSString,则副本相当于“保留”。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-12-07
    • 2019-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-13
    相关资源
    最近更新 更多