0

基本上我想循环浏览4个网页,从每个页面获取6个数据,循环结束时数组中共有24个数据,然后显示该数组最后添加的数据(数组中的第24个对象) /(第4个网页的第6个数据)在message.text标签上。

信息:

i) 我要循环浏览的 4 个网页:

http://apims.doe.gov.my/apims/hourly1.php

http://apims.doe.gov.my/apims/hourly2.php

http://apims.doe.gov.my/apims/hourly3.php

http://apims.doe.gov.my/apims/hourly4.php

ii) NSURLSession 任务从页面中获取 6 个数据(“AQI1”、“AQI2”、“AQI3”、“AQI4”、“AQI5”、“AQI6”),并添加到空 [String] 数组(“AQI "):

var urlContent = NSString(data: data, encoding: NSUTF8StringEncoding) as NSString!
var cutCut = urlContent.componentsSeparatedByString("<td>Kota Tinggi</td>")
var cut = cutCut[1].componentsSeparatedByString("<b>")
var arr1 = cut[1].componentsSeparatedByString("</b>")
var AQI1 = arr1[0] as! String
var arr2 = cut[2].componentsSeparatedByString("</b>")
var AQI2 = arr2[0] as! String
var arr3 = cut[3].componentsSeparatedByString("</b>")
var AQI3 = arr3[0] as! String
var arr4 = cut[4].componentsSeparatedByString("</b>")
var AQI4 = arr4[0] as! String
var arr5 = cut[5].componentsSeparatedByString("</b>")
var AQI5 = arr5[0] as! String
var arr6 = cut[6].componentsSeparatedByString("</b>")
var AQI6 = arr6[0] as! String

self.AQI.extend([AQI1, AQI2, AQI3, AQI4, AQI5, AQI6])

iii) Var "taskerror" 被创建为一个布尔值来检查任务中不需要的错误,如果 Var "taskerror" = true 最后运行一个 Func ERROR( ) 。



这是整个代码,我将其放在 IBAction 按钮下(我在按钮之前创建了 var AQI = [String] ( ))

AQI.removeAll(keepCapacity: true)

var pages = ["1", "2", "3", "4"]

    for object in pages {

        var url = NSURL(string: "http://apims.doe.gov.my/apims/hourly" + object + ".php")

        var task = NSURLSession.sharedSession().dataTaskWithURL(url!, completionHandler: { (data, response, error) -> Void in

            var taskerror = false

            if error == nil {

                var urlContent = NSString(data: data, encoding: NSUTF8StringEncoding) as NSString!
                var cutCut = urlContent.componentsSeparatedByString("<td>Kota Tinggi</td>")
                var cut = cutCut[1].componentsSeparatedByString("<b>")
                var arr1 = cut[1].componentsSeparatedByString("</b>")
                var AQI1 = arr1[0] as! String
                var arr2 = cut[2].componentsSeparatedByString("</b>")
                var AQI2 = arr2[0] as! String
                var arr3 = cut[3].componentsSeparatedByString("</b>")
                var AQI3 = arr3[0] as! String
                var arr4 = cut[4].componentsSeparatedByString("</b>")
                var AQI4 = arr4[0] as! String
                var arr5 = cut[5].componentsSeparatedByString("</b>")
                var AQI5 = arr5[0] as! String
                var arr6 = cut[6].componentsSeparatedByString("</b>")
                var AQI6 = arr6[0] as! String

                self.AQI.extend([AQI1, AQI2, AQI3, AQI4, AQI5, AQI6])

            } else {
                taskerror = true
            }

            dispatch_async(dispatch_get_main_queue()) {
                if taskerror {
                    self.ERROR()
                } else {
                    if self.AQI.count == 24 {
                        self.message.text = self.AQI[23]
                    }
                }
            }

        })

        task.resume()

    }

我的问题是:

1)在4个URL上运行任务的顺序是随机的,导致数组AQI中6组数据的显示顺序是随机的,因此数组AQI中的最后(第24)个对象不固定,即使第 4 个 URL 的最后一个数据没有改变。

2) 在 message.text 上显示 AQI[23] 之前使用 println(self.AQI),我可以看到这组 6 个数据是随机排序的。

3) 在 var task 之前使用 println(object) 显示循环相应地通过 URL “1”、“2”、“3”、“4”运行。但是如果放在var task里面,它会显示循环是如何随机运行的(例如“2”、“4”、“3”、“1”),从而产生对应的(2)中提到的随机排列的数组AQI。

我的问题是

1)为什么在任务中循环随机运行?(不是根据设置的 var pages = ["1", "2", "3", "4"] )

2)如何让任务通过循环有序运行,使数组AQI中的最后一个对象(第24个)始终相同?

注意:我知道如果我想要最后一个数据,我可以只运行第 4 个 URL,但我想稍后在需要所有 24 个数据时添加更多代码。

ps有没有更好的方法来做我想做的事?

4

1 回答 1

0

我在下面的回答不是直接解决您的问题,而是对我的评论的跟进,解释了为什么您以随机顺序获得回复。尽管如此,我相信它会很快让你找到你的解决方案。:)

打开调试控制台,多次启动此代码(改编自您的代码)并观察打印结果。

var results = [Int:[String]]()

for index in 1...4 {
    println("Loop index: \(index)")

    var url = NSURL(string: "http://apims.doe.gov.my/apims/hourly\(index).php")

    var task = NSURLSession.sharedSession().dataTaskWithURL(url!, completionHandler: { (data, response, error) -> Void in

        var taskerror = false

        if error == nil {

            var urlContent = NSString(data: data, encoding: NSUTF8StringEncoding) as NSString!
            var cutCut = urlContent.componentsSeparatedByString("<td>Kota Tinggi</td>")
            var cut = cutCut[1].componentsSeparatedByString("<b>")
            var arr1 = cut[1].componentsSeparatedByString("</b>")
            var AQI1 = arr1[0] as! String
            var arr2 = cut[2].componentsSeparatedByString("</b>")
            var AQI2 = arr2[0] as! String
            var arr3 = cut[3].componentsSeparatedByString("</b>")
            var AQI3 = arr3[0] as! String
            var arr4 = cut[4].componentsSeparatedByString("</b>")
            var AQI4 = arr4[0] as! String
            var arr5 = cut[5].componentsSeparatedByString("</b>")
            var AQI5 = arr5[0] as! String
            var arr6 = cut[6].componentsSeparatedByString("</b>")
            var AQI6 = arr6[0] as! String

            results[index] = [AQI1, AQI2, AQI3, AQI4, AQI5, AQI6]

        } else {
            taskerror = true
        }

        dispatch_async(dispatch_get_main_queue()) {
            if taskerror {
                println(taskerror)
            } else {
                println("Result index: \(index) - Content: \(results[index]!)")
            }
        }

    })

    task.resume()
}
  • 1:

在此处输入图像描述

  • 2:

在此处输入图像描述

现在您看到每个任务确实是根据循环索引按顺序启动的,但是结果是异步返回的,具体取决于每个任务从网络获取数据所花费的时间。而且每次启动序列时都不相同,因为网络速度当然不是恒定的。

在我的示例中,我使用 Dictionary 而不是 Array 来存储结果,它允许我向您展示您对正确的请求获得了正确的响应,只是您以随机顺序获得结果,这是由于异步的性质任务。

于 2015-05-22T08:38:31.797 回答