2015-12-08 100 views
0

我是一个绝对快捷的初学者,并试图构建我的第一个应用程序。当我写了一段代码时,我不认为它会第一次工作,并且在它发生时是可疑的。在重复循环中,我在图表上设置了行,并想在行的左侧添加一个UILabel。我想我可以let一个新的UILabel创建主视图的子视图,但不知道如何让它为每个迭代创建一个唯一的变量名称。为什么这个有效?在重复循环中添加UILabel

repeat { 
     // code to make the lines here 

     // create label with minute number for each line 
     let minuteLabel = UILabel(frame: CGRectMake(0, 0, 20, 20)) 

     // code to position the label here 

     minuteLabel.text = String(numberOfLines) 

     // code to style the label 

     self.addSubview(minuteLabel) 

     numberOfLines-- 
    } 
    while numberOfLines > 0 

我认为这将最终只是创建一个子视图和它的文本将numberOfLines的最后一次迭代,但它完美地工作。这是否意味着我的主图形视图现在有(numberOfLines)个UILabel子视图,每个子视图具有相同的名称?

是否有可能在这个重复循环的范围之外单独访问每一个?

感谢您帮助我理解这一点!

+0

有时代码第一次工作,也让我感到惊讶。 – zaph

回答

0

我认为区分对象的属性和对象的引用很重要。当您编写“每个具有相同名称的UILabel子视图的数量”并非准确的短语时,因为这些标签没有名称。一个对象(在这种情况下是一个标签)没有关于它可能存在多少个引用或者这些引用可能在编译时被命名的信息。

在您的代码示例中,您将创建一个常量引用minuteLabel并将其指定为指向标签。该常数只存在于该循环的一次迭代范围内。在当前循环迭代结束时,该引用被丢弃。如果没有对标签对象的引用,则可能无法再找到它,但这并不意味着标签不存在。在这种情况下,您将标签添加为某个其他视图的子视图(self)。该父视图创建了自己对该标签的强烈引用,并按照Automatic Reference Counting的规则,只要有强烈的引用,标签就会继续存在。您甚至可以使用self.subviews再次找到这些标签,但您可能很难找出哪个标签现在不再提供每个标签。

注意到,虽然给出参考的名称(如minuteLabel)对您而言很有意义,但它对运行您的应用的计算机没有意义或甚至不为人知。这个名字有助于我们人类跟踪计算机内存中发生的指向UILabel的特定位置,但是您将无法使用相同的名称从代码中的某个其他范围中找到相同的标签。您的应用在不同范围内可能有多个名为minuteLabel的引用,并且它们甚至可以指向不同类型的对象,具有相同的名称不会使它们成为同一个对象。

在像那里你有一个对象的集合,并希望能够找到每一个以后再次一个很好的解决方案通常使用某种集合类型的情况下,一个数组允许您按照已知的顺序存储对这些标签的引用,然后您可以在特定的索引处查找标签,字典将允许您在某些已知的“关键”对象下存储对这些标签的引用,稍后可以使用相同的密钥来检索特定的标签。

尝试为每个对象动态创建一个常量变量(例如创建minuteLabel0常量,然后是minuteLabel1常量...的循环)时,您不会找到很大的成功。如果不清楚为什么那么值得建立一个更加精确的心智模型来说明你的程序的编译和执行阶段之间的区别。

+0

谢谢,这使得它更清晰。在这种情况下,现在我不认为我需要再次引用它们 - 它们更容易被设置和忘记,但我相信在将来我会创建类似的东西,并且会努力想出来如何再次访问它们! –

0

首先suviews没有引用名称,所以他们不会都有相同的名称。它们包含在可以通过引用索引访问的数组中。因此,当你将它添加添加到适当的阵列和例如每个子视图被访问:

self.subviews[0] 

每个元素随后将持有相同的子视图您正在创建的循环。希望这有助于为您清除它。