为什么我们可以在方法的实现中使用自定义/基础类的实例而无需先为实例执行alloc和init?

时间:2015-07-14 18:09:59

标签: objective-c

这个问题是基于斯坦福iOS系列2014年第一次演讲的代码(目标-c)。

我们创建了一个名为Card的类,其中包含一个名为match:的方法,该方法将用于确定不同的牌在游戏中如何相互匹配,并且此方法将参数作为参数NSArray调用*otherCards,我们使用名为Card的{​​{1}}实例在此方法的实现中迭代此数组。

我的问题是 - 我们如何才能声明我们的类卡的实例,即*card并在for循环中将其用作迭代变量而不首先分配和实例化它?同样,我们如何将* otherCards声明为NSArray的一个实例,然后在分配和初始化之前在for循环中循环使用它?

我意识到这可能会在后面的代码中完成,但为什么编译器至少不会对此发出警告?

以下是代码:

*card

3 个答案:

答案 0 :(得分:2)

我认为你的问题是关于这个循环:

for (Card *card in otherCards) {
    ...
}
  

我们怎样才能将* otherCards声明为NSArray的一个实例,然后再使用它

您不需要分配和初始化otherCards,因为它作为参数提供给函数match。调用者负责初始化它。你不能躲避初始化,只是它在其他地方完成:

Card * myCard = ...               // init the varible here
NSArray * otherCards = ...        // init the array here
int n = [myCard match:otherCards] // otherCards is now initialized. Don't need to 
                                  // do it again inside your method
  

我们如何才能声明我们的类Card的实例,即*card并将其用作for循环中的迭代变量

card不是新对象。它只是指向otherCards数组中的现有对象,因此不需要alloc和init。

您确实在card循环{@ 1}}中将Card声明为for类型的指针。这是一种语法糖,使代码更简洁。如果你愿意,你可以做很多事情:

for (Card * card in otherCards)

答案 1 :(得分:1)

…(NSArray *)otherCardsCard *card in都是占位符。

otherCards是参数名称。方法match期望(初始化的)NSArray作为参数在方法中本地处理数组。关联指针(NSArray *)保存对数组的引用,直到方法保留为止。

Card *card in是一个临时索引指针,用于保存每次迭代对数组的一个(初始化)项的引用

答案 2 :(得分:1)

实例确实存在;这些只是您为他们使用的本地名称。你是对的,如果没有先创建它们就不会发生任何事情,但创建它们不是这种方法的工作。

没有编译器警告,因为您在编译时没有做错任何事情:您已经采用NSArray类型的对象并通过它迭代(使用for( ... in theArray )语法) ,每个成员都有一个临时名称。该数组在运行时可能不存在(be nil),但ObjC编译器无法知道这一点;即使它发生了,结果也没什么,不是错误。

使用此方法的后续代码将如下所示:

Card * aCard = [[Card alloc] init];
// set aCard's properties
NSArray * cards = @[anotherCard, aThirdCard, stillAnotherCard];
[card match:cards];

创建所有这些对象,然后根据需要传递给方法。