Objective c 如何在实现文件中引用成员变量

Objective c 如何在实现文件中引用成员变量,objective-c,interface,Objective C,Interface,我正在学习Objective-C,并试图将类定义从实现中分离出来,如下所示。 现在,在代码中,我想引用以下两种: NSString *CarMotorCode; NSString *CarChassisCode; 在实现文件中。我试图使用: self.CarMotorCode; self.CarChassisCode; 但它不起作用。请告诉我如何参考它好吗 注意:请让我知道实现部分括号内的变量的正确命名约定是什么?它们是成员变量吗 Car2.m: #import <Foundation

我正在学习Objective-C,并试图将类定义从实现中分离出来,如下所示。 现在,在代码中,我想引用以下两种:

NSString *CarMotorCode;
NSString *CarChassisCode;
在实现文件中。我试图使用:

self.CarMotorCode;
self.CarChassisCode;
但它不起作用。请告诉我如何参考它好吗

注意:请让我知道实现部分括号内的变量的正确命名约定是什么?它们是成员变量吗

Car2.m

#import <Foundation/Foundation.h>
#import "Car2.h"

@implementation Car2

-(id) initWithMotorValue:(NSString *)motorCode andChassingValue:(NSInteger)ChassisCode {
    self
}

@end

您已经声明了实例变量(IVAR)。要获得“点语法”,您需要声明属性。“点语法”是一种语法糖,它利用了在声明属性时为您合成的“访问器方法”。(FWIW,无论如何,建议不要手动声明IVAR,而是声明属性并让编译器合成必要的IVAR。请参阅和。)

因此:

您的
init
方法可能如下所示:

@implementation Car2

- (id)initWithMotorCode:(NSString *)motorCode chassisCode:(NSString *)chassisCode {
    if ((self = [super init])) {
        _motorCode = [motorCode copy];
        _chassisCode = [chassisCode copy];
    }
    return self;
}

@end
这将在幕后为您合成IVAR
\u motorCode
\u chassisCode
,但您通常不会直接与它们交互(在
init
方法中除外,在这种情况下,您应该避免访问属性)。但是在其余的实例方法中,您可以只使用属性
self.motorCode
self.chassisCode

一些不相关的注释:

  • 我在您的房产名称中删除了
    汽车
    前缀。在处理汽车对象时,包含该前缀似乎是多余的

  • 作为惯例,我用小写字母开始我的财产名称

  • 我更改了
    init
    方法签名以更好地镜像属性名称(例如,不是
    initWithMotorValue
    ,而是
    initWithMotorCode

  • 或者,您可以使用
    strong
    内存限定符,而不是
    copy
    。例如

    @interface Car2: NSObject
    @property (nonatomic, strong) NSString *motorCode;
    @property (nonatomic, strong) NSString *chassisCode;
    
    - (id)initWithMotorCode:(NSString *)motorCode chassisCode:(NSString *)chassisCode;
    @end
    

    但是我们经常使用
    copy
    来保护我们,防止有人将
    NSMutableString
    作为这些属性之一传递给我们,然后在我们背后对其进行变异。但这取决于你

  • 您将
    chassisCode
    定义为ivar声明中的字符串,但在init方法签名中定义为
    NSInteger
    。显然,如果它是一个
    NSInteger
    ,则相应地更改这两者:

    @interface Car2: NSObject
    @property (nonatomic, copy) NSString *motorCode;
    @property (nonatomic) NSInteger chassisCode;
    
    - (id) initWithMotorCode:(NSString *)motorCode chassisCode:(NSInteger)chassisCode;
    
    @end
    

  • 如果您想知道为什么我没有在
    init
    方法中使用属性访问器方法,请参阅


您的思路是正确的,但“self.CarMotorCode;”是错误的语法。你需要;自我->CarMotorCode@johnelemans请告诉我这两种符号的区别好吗?是因为我们引用了一个私有变量吗?点表示法是一种语法糖,它提供了对属性访问器方法的方便访问。如果需要取消引用某个对象的IVAR,则使用
->
。(注意,如果使用IVAR,您可以使用
self->motorCode
,或者您通常可以省略
self->
部分,直接使用
motorCode
。但无论如何,建议使用带有点语法的属性。)
@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;
}
@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;
}