1

在我正在创建的项目中,我有各种课程。我的一个类有一个 NSMutableArray 的实例,它包含我的另一个类的对象。我以为我对这个话题有一个深刻的理解,但不知怎的,它又在我脑海里乱七八糟了。

当初始化这个类的一个实例时,我有这个 initilize 方法:

- (MMShowMovement *) initWithMovementName: (NSString *) name andNumber: (NSInteger) number {

 if( [super init] ) {

  [self setMovementTitle: name];
  [self setMovementNumber: number];

  [self setDotArray: [[NSMutableArray alloc] init]];

 }

 return self;

}

稍后,在创建此类的实例后,我可以将对象添加到 NSMutableArray“dotArray”。这是那个方法。

- (void) addDot: (MMDot *) dot {

 [dotArray addObject: dot]; 

}

(我知道,它很简单)我想知道,当我在此方法中使用“dotArray”时,我正在访问调用此方法的类的实例的 dotArray 对象,对吗?还是我也应该在这里使用 self 关键字?

- (void) addDot: (MMDot *) dot {

 [[self dotArray] addObject: dot]; 

}

老实说,我不太确定。我相信是前者,但我不确定为什么。而且在这个方法中不需要使用self关键字,为什么我必须在初始化器中使用它来访问对象呢?

4

3 回答 3

3

self是指向当前接收者的指针 - 它指的是接收到消息的对象。
您可以使用 self 来访问执行当前方法的对象。

在您的情况下,这意味着如果类型的对象 XMMShowMovement收到addDot:消息,则 self 包含指向 X 的指针。
您可以通过dotArray三种不同的方式访问:

[dotArray addObject:dot]; //directly access the instance variable dotArray
[[self dotArray] addObject:dot]; //access dotArray with an accessor method
//--or--
[self.dotArray addObject:dot]; //access dotArray with an accessor method using dot-syntax

如果您使用自动 KVO 通知,则必须使用访问器(而不是直接操作 ivar)来触发通知。
要确保通过其访问器方法访问变量,您必须添加前缀self.

于 2010-01-03T10:35:36.910 回答
2

[self dotArray] 调用对象的“dotArray”选择器(方法)。如果没有这样的方法,你会得到一个错误。您不能以这种方式访问​​实例变量,除非它是一个属性并且您已经为它合成了这个 getter 方法。

[dotArray addObject] 只是访问变量并调用由 NSMutableArray 指定的内置方法。

[self setMovementTitle:]、[self setMovementNumber:] 和 [self setDotArray:] 都是方法调用。方法调用总是需要对象引用。

在 init 中,您可能还说过 [dotArray addObject](当然是在初始化变量之后)。

于 2010-01-03T09:28:34.543 回答
2

通常我们会写

self = [super init]  

因为super的初始化方法可能会返回一个与分配的对象不同的对象。这就是为什么我们在 initxxx 方法中使用self而我们不需要在其他类型的方法中使用self的原因。

我从《在 Mac 上学习 Objective-C,第 10 章对象初始化,Mark Dalrymple 和 Scott Knaster,Apress 这本书清楚地学到了这些东西。

本书的摘录:
实例变量位于与隐藏的 self 参数有固定距离的内存位置。如果从 init 方法返回一个新对象,我们需要更新 self以便任何后续实例变量引用影响内存中的正确位置。

于 2010-01-03T09:46:11.510 回答