objective-c - 如何在实现文件中引用成员变量
问题描述
我正在学习Objective-C,我正在尝试将类定义与实现分开,如下所示。现在在代码中我想引用这两个:
NSString *CarMotorCode;
NSString *CarChassisCode;
在实现文件中。我试图使用:
self.CarMotorCode;
self.CarChassisCode;
但它不起作用。请让我知道如何引用它。
注意:请让我知道在实施部分括号内的变量的正确命名约定是什么?它们是成员变量吗?
车2.m:
#import <Foundation/Foundation.h>
#import "Car2.h"
@implementation Car2
-(id) initWithMotorValue:(NSString *)motorCode andChassingValue:(NSInteger)ChassisCode {
self
}
@end
汽车2.h
#ifndef Car2_h
#define Car2_h
@interface Car2 : NSObject {
NSString *CarMotorCode;
NSString *CarChassisCode;
}
-(id) initWithMotorValue: (NSString *) motorCode andChassingValue: (NSInteger) ChassisCode;
-(void) startCar;
-(void) stopCrar;
@end
#endif /* Car2_h */
解决方案
您已经声明了实例变量(ivars)。要获得“点语法”,您需要声明属性。“点语法”是使用声明属性时为您合成的“访问器方法”的语法糖。(FWIW,建议不要手动声明 ivars,而是声明属性并让编译器合成必要的 ivars。请参阅Programming with Objective-C: Properties Control Access to an Object's Values and Practical Memory Management: Use Accessor Methods to使内存管理更容易。)
因此:
@interface Car2: NSObject
@property (nonatomic, copy) NSString *motorCode;
@property (nonatomic, copy) NSString *chassisCode;
- (id)initWithMotorCode:(NSString *)motorCode chassisCode:(NSString *)chassisCode;
@end
您的init
方法可能如下所示:
@implementation Car2
- (id)initWithMotorCode:(NSString *)motorCode chassisCode:(NSString *)chassisCode {
if ((self = [super init])) {
_motorCode = [motorCode copy];
_chassisCode = [chassisCode copy];
}
return self;
}
@end
这将在幕后为您合成 ivars _motorCode
,_chassisCode
但您通常不会直接与它们交互(在init
方法中除外,在这种情况下,您应该避免访问属性)。但是在其余的实例方法中,您可以只使用属性self.motorCode
和self.chassisCode
.
一些不相关的注释:
我在您的属性名称中删除了
car
前缀。在处理汽车对象时包含该前缀似乎是多余的。作为约定,我以小写字母开头我的属性名称。
我更改了
init
方法签名以更好地反映属性名称(例如 notinitWithMotorValue
but ratherinitWithMotorCode
)。或者,您可以使用
strong
内存限定符而不是copy
. 例如@interface Car2: NSObject @property (nonatomic, strong) NSString *motorCode; @property (nonatomic, strong) NSString *chassisCode; - (id)initWithMotorCode:(NSString *)motorCode chassisCode:(NSString *)chassisCode; @end
和
- (id)initWithMotorCode:(NSString *)motorCode chassisCode:(NSString *)chassisCode { if ((self = [super init])) { _motorCode = motorCode; _chassisCode = chassisCode; } return self; }
但是我们经常
copy
用来保护我们免受某人将 aNSMutableString
作为这些属性之一传递,然后在我们背后对其进行变异。但这取决于你。您在 ivar 声明中定义
chassisCode
为一个字符串,但NSInteger
在您的 init 方法签名中定义为一个字符串。显然,如果它是NSInteger
,请相应地更改两者:@interface Car2: NSObject @property (nonatomic, copy) NSString *motorCode; @property (nonatomic) NSInteger chassisCode; - (id) initWithMotorCode:(NSString *)motorCode chassisCode:(NSInteger)chassisCode; @end
和
- (id)initWithMotorCode:(NSString *)motorCode chassisCode:(NSInteger)chassisCode { if ((self = [super init])) { _motorCode = [motorCode copy]; _chassisCode = chassisCode; } return self; }
如果您想知道为什么我没有在方法中使用属性访问器方法
init
,请参阅实用内存管理:不要在初始化方法中使用访问器方法和 dealloc。
推荐阅读
- python - 如何获得差异混合模式?
- javascript - 如何使用 JSDoc 记录外部类
- javascript - firebase 只读 React Native
- javascript - Flappy Bird 代码不起作用 - JavaScript
- java - 两个服务在android中不能一起工作
- c++ - 导出到 HTML5 FWebSocketsModule 不起作用
- vue.js - 将 vue 项目构建为“库”后导入路径错误
- c# - 从托管服务中调用 IServiceProvider.CreateScope 是一种反模式吗?
- join - flink 如何组合流和乘法映射
- haskell - 带有数据的实例函子