objective-c - 为什么方法没有被调用
问题描述
我正在尝试学习如何创建类和对象以及如何在 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);
}
主文件
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
我究竟做错了什么?
解决方案
City
问题是从未设置过的实例变量。中的代码setName:Age:Population:
将实例变量( 、 和 )的值分配给name
参数age
变量population
(theName
、theAge
和thePopulation
)。交换这些将导致 setter 将参数分配给实例变量:
name = theName;
age = theAge;
population = thePopulation;
也就是说,使用属性(而不是实例变量和手动 getter 和 setter)并使用初始化程序来设置初始值更符合 Objective-C 的习惯。通过这些更改, 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
关于这段代码有两点需要注意:
字符串在初始化程序和属性中都被复制,以防止
NSMutableString
传递 a 并在以后发生变异(这也会改变 的值name
。对于传递不可变对象的常见情况NSString
,副本相当于一个“保留”。在初始化器中赋值时使用合成的实例变量。这是为了防止子类覆盖这些属性中的任何一个,并在对象完全初始化之前运行自定义 setter 方法(将其所有变量设置为其初始值)。这仅适用于初始化器、自定义设置器和 dealloc。其他一切都应该使用这些属性来访问和修改这些值。
推荐阅读
- eclipse - Not able to Cmd+ Click code coming through dependencies in STS 4
- reactjs - React.js child state not re-rendering even after calling setState?
- unity3d - 为什么按“播放”时游戏场景为空?
- python - 将数组排序到索引数组指定的箱中的最有效方法?
- python - 如何创建与 MySQL 和 Sqlite3 一样好的 SQL 语句?
- spring - 在@Configuration 类中有@Autowire 或@Inject 可以吗
- weblogic12c - ATG RunAssembler 不打包 weblogic-application.xml
- r - gmailR - 通过 R 发送多封带有附件的电子邮件
- java - 使用 vaadin 在基于 Spring 的项目中包含 css
- jquery - Ajax Post 和 Asp.Net webApplication