首页 > 解决方案 > 如何在实现文件中引用成员变量

问题描述

我正在学习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 */

标签: objective-cinterface

解决方案


您已经声明了实例变量(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.motorCodeself.chassisCode.

一些不相​​关的注释:

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

  • 作为约定,我以小写字母开头我的属性名称。

  • 我更改了init方法签名以更好地反映属性名称(例如 not initWithMotorValuebut rather initWithMotorCode)。

  • 或者,您可以使用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


推荐阅读