为什么这行得通?在重复循环中添加 UILabel
Why does this work? Adding UILabel in repeat loop
我绝对是 swift 初学者,正在尝试构建我的第一个应用程序。当我编写一些代码时,我不希望它第一次运行并且在它运行时我很怀疑。在一个重复循环中,我在图表上设置线条,并想在线条的左侧添加一个 UILabel。我想我可以 let
一个新的 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 子视图?
是否可以在此重复循环范围之外单独访问每个?
感谢您帮助我理解这一点!
首先,suviews 不是按名称引用的,因此它们不会都具有相同的名称。它们包含在一个数组中,可以通过引用索引来访问该数组。因此,当您添加每个子视图时,它会被添加到适当的数组中,例如可以通过以下方式访问:
self.subviews[0]
然后,每个元素都将包含您在循环中创建的相同子视图。希望这可以帮助您解决问题。
我认为区分对象的属性和对对象的引用很重要。当您写 "number of UILabel subviews each with the same name" 时,这不是一个准确的短语,因为这些标签 没有名称 。一个对象(在这种情况下是一个标签)没有关于它可能存在多少引用或这些引用在编译时可能被命名的信息。
在您的代码示例中,您创建了一个常量引用 minuteLabel
并将其指定为指向一个标签。该常量仅存在于 repeat
循环的一次迭代范围内。在当前循环迭代结束时,该引用被丢弃。如果没有对标签对象的引用,您可能无法再找到它,但这并不意味着标签不存在。在这种情况下,您将标签添加为某个其他视图 (self
) 的子视图。该父视图创建了自己对标签的强引用,并且根据 Automatic Reference Counting 的规则,只要存在对它的强引用,该标签就会继续存在。您甚至可以使用 self.subviews
再次找到这些标签,但是您可能很难确定哪个标签是哪个标签,因为您不再对每个标签都有引用。
注意虽然您提供参考的名称(如 minuteLabel
)对您有意义,但计算机 运行 甚至不知道您的应用程序。该名称帮助我们人类跟踪计算机内存中恰好指向 UILabel
的特定位置,但您将无法使用相同的名称从代码中的其他范围定位相同的标签。您的应用程序可能在不同的范围内有许多名为 minuteLabel
的引用,它们甚至可以指向不同类型的对象,具有相同的名称并不意味着它们是同一件事。
在这种情况下,您有一个对象集合并且希望以后能够再次定位每个对象,一个好的解决方案通常是使用某种集合类型;一个数组将允许您以已知顺序存储对这些标签的引用,然后您可以在特定索引处查找标签,一个字典将允许您将对这些标签的引用存储在某个已知的 "key" 对象下,然后您稍后可以使用等效密钥来检索特定标签。
尝试为每个对象动态创建一个常量变量(例如,创建一个 minuteLabel0
常量然后创建一个 minuteLabel1
常量的循环,...)不会取得很大的成功。如果不清楚原因,那么可能值得为程序的编译阶段和执行阶段之间的差异建立一个更精确的心理模型。
我绝对是 swift 初学者,正在尝试构建我的第一个应用程序。当我编写一些代码时,我不希望它第一次运行并且在它运行时我很怀疑。在一个重复循环中,我在图表上设置线条,并想在线条的左侧添加一个 UILabel。我想我可以 let
一个新的 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 子视图?
是否可以在此重复循环范围之外单独访问每个?
感谢您帮助我理解这一点!
首先,suviews 不是按名称引用的,因此它们不会都具有相同的名称。它们包含在一个数组中,可以通过引用索引来访问该数组。因此,当您添加每个子视图时,它会被添加到适当的数组中,例如可以通过以下方式访问:
self.subviews[0]
然后,每个元素都将包含您在循环中创建的相同子视图。希望这可以帮助您解决问题。
我认为区分对象的属性和对对象的引用很重要。当您写 "number of UILabel subviews each with the same name" 时,这不是一个准确的短语,因为这些标签 没有名称 。一个对象(在这种情况下是一个标签)没有关于它可能存在多少引用或这些引用在编译时可能被命名的信息。
在您的代码示例中,您创建了一个常量引用 minuteLabel
并将其指定为指向一个标签。该常量仅存在于 repeat
循环的一次迭代范围内。在当前循环迭代结束时,该引用被丢弃。如果没有对标签对象的引用,您可能无法再找到它,但这并不意味着标签不存在。在这种情况下,您将标签添加为某个其他视图 (self
) 的子视图。该父视图创建了自己对标签的强引用,并且根据 Automatic Reference Counting 的规则,只要存在对它的强引用,该标签就会继续存在。您甚至可以使用 self.subviews
再次找到这些标签,但是您可能很难确定哪个标签是哪个标签,因为您不再对每个标签都有引用。
注意虽然您提供参考的名称(如 minuteLabel
)对您有意义,但计算机 运行 甚至不知道您的应用程序。该名称帮助我们人类跟踪计算机内存中恰好指向 UILabel
的特定位置,但您将无法使用相同的名称从代码中的其他范围定位相同的标签。您的应用程序可能在不同的范围内有许多名为 minuteLabel
的引用,它们甚至可以指向不同类型的对象,具有相同的名称并不意味着它们是同一件事。
在这种情况下,您有一个对象集合并且希望以后能够再次定位每个对象,一个好的解决方案通常是使用某种集合类型;一个数组将允许您以已知顺序存储对这些标签的引用,然后您可以在特定索引处查找标签,一个字典将允许您将对这些标签的引用存储在某个已知的 "key" 对象下,然后您稍后可以使用等效密钥来检索特定标签。
尝试为每个对象动态创建一个常量变量(例如,创建一个 minuteLabel0
常量然后创建一个 minuteLabel1
常量的循环,...)不会取得很大的成功。如果不清楚原因,那么可能值得为程序的编译阶段和执行阶段之间的差异建立一个更精确的心理模型。