致命错误:in循环swift 3的索引超出范围

时间:2016-10-19 00:53:06

标签: ios arrays swift pdf for-loop

我试图在Github上使用simplePDF框架创建一个保存到pdf方法。我有几个数组,并尝试使用for循环。这是我的第一次,但我不明白为什么我会得到致命错误:索引超出范围。这是我的代码。

let A4paperSize = CGSize(width: 595, height: 842)
    let pdf = SimplePDF(pageSize: A4paperSize)
    pdf.setContentAlignment(.center)

    let count = Globals.datesArray.count
    var sum = 0

    for index in 0...count {
        pdf.addText(Globals.datesArray[index])
        pdf.addText(Globals.titleArray[index])
        pdf.addText(Globals.descriptionArray[index])
        sum += index
    }

    let pdfData = pdf.generatePDFdata()

非常感谢任何帮助。谢谢!

3 个答案:

答案 0 :(得分:4)

两个答案都是正确的,但两者都不理想。

这样可行:

for index in 0..<count {

然而,使用起来要好得多:

for index in Globals.datesArray.indicies

这样就为您创建了范围,并消除了输入错误的可能性(...而不是..<

旁注:

我担心的是您使用3个数组来存储相关数据。维基百科有一个关于pros and cons of parallel arrays的部分。他们在现代高级编程中确实没有地位。他们工作繁琐,而且非常脆弱。例如,如果您将元素添加到中间 datesArraytitleArray,但忘记在descriptionArray中添加说明,突然之间,您的日期/标题和说明之间存在不匹配。

您应该尝试使用class or struct。例如,您可能需要这样的结构声明:

struct Thing { //TODO: give me a name!
    let date: Date
    let title: String
    let description: String
}

这可以让你改变一个凌乱的并行结构:

let datesArray = [date0, date1, date2]
let titlesArray = ["title0", "title1", "title2"]
let descriptionsArray = ["Description 0", "Description 1", "Description 2"]

就像这样:

let things = [
    Thing(
        date: date0,
        title: "title0"
        description: "Description 0"
    ),
    Thing(
        date: date1,
        title: "title1"
        description: "Description 1"
    ),
    Thing(
        date: date2,
        title: "title2"
        description: "Description 2"
    ),
]

通过第二次声明,所有与单个Thing相关的信息都会以内聚方式存储。它可以让您更轻松地进行添加/编辑。没有更多的计数元素,以确保他们排队!

使用这样的结构,您的代码可以这样写:

let A4paperSize = CGSize(width: 595, height: 842)
let pdf = SimplePDF(pageSize: A4paperSize)
pdf.setContentAlignment(.center)

var sum = 0

for (index, thing) in things.enumerated() {
    pdf.addText(thing.date)
    pdf.addText(thing.title)
    pdf.addText(thing.description)
    sum += index
}

let pdfData = pdf.generatePDFdata()

该代码段使用enumerated(),可让您迭代元素及其索引。这样,我们就不必在循环体中下标我们的数组。

但是,在这种情况下,sum将始终是0, 1, ... , count的总和。这等于(count * (count + 1)) / 2,因此我们可以进一步简化代码:

let A4paperSize = CGSize(width: 595, height: 842)
let pdf = SimplePDF(pageSize: A4paperSize)
pdf.setContentAlignment(.center)

for (index, thing) in things.enumerated() {
    pdf.addText(thing.date)
    pdf.addText(thing.title)
    pdf.addText(thing.description)
}

let pdfData = pdf.generatePDFdata()

let sum = (count * (count + 1)) / 2

现在,由于我们不再在index循环体中使用for,我们可以使用常规迭代,而不使用enumerated()

let A4paperSize = CGSize(width: 595, height: 842)
let pdf = SimplePDF(pageSize: A4paperSize)
pdf.setContentAlignment(.center)

for index in things {
    pdf.addText(thing.date)
    pdf.addText(thing.title)
    pdf.addText(thing.description)
}

let pdfData = pdf.generatePDFdata()

let sum = (count * (count + 1)) / 2

答案 1 :(得分:2)

David的回答:

for index in 0...count {

可能是

for index in 0..<count {

这将循环直到但不包括计数。

答案 2 :(得分:1)

我认为它应该是let count = Globals.datesArray.count - 1。如果Globals.count == 3,则索引为[0,1,2],[3]将超出范围。