增量计数器和array.count在使用调度队列时给出不一致的答案

时间:2015-05-05 18:46:06

标签: ios arrays swift cocoa-touch grand-central-dispatch

我有一个简单的应用程序,可以从CMPedometer中检索最后7天的小时数据(168条记录)并将它们存储在一个数组中。然后我通过该数组找到阵列中行进的最高距离,并在视图的标签中显示。

    var GlobalMainQueue: dispatch_queue_t {
        return dispatch_get_main_queue()
    }
    var exerciseDataGroup = dispatch_group_create()
    dispatch_group_enter(exerciseDataGroup)
    var modelController = ModelController.init()
    dispatch_group_leave(exerciseDataGroup)


    dispatch_group_notify(exerciseDataGroup, GlobalMainQueue){
        self.BestHourOfTheWeekLabel.text = "Your best distance of the last 7 days was \(modelController.getHighestHourInWeek())"
        }

上面的代码在我的viewDidLoad方法中。在modelController初始化程序中,我运行getDistanceForEachHourInWeek()来检索所有距离记录并填充数组以保存它们。

func getDistanceForEachHourInWeek(){
    //****TESTING****
    var count = 0
    var errorCount = 0

    for day in 0...7 {
        //Getting Todays Date
        var today = NSDate()
        let calendar = NSCalendar.currentCalendar()
        //breaking date into components
        var requestedTodaysDateComponents: NSCalendarUnit = .CalendarUnitYear |
            .CalendarUnitMonth |
            .CalendarUnitDay |
            .CalendarUnitHour |
            .CalendarUnitMinute
        var todaysDateComponents = calendar.components(requestedTodaysDateComponents,
            fromDate: today)
        //modifying components to get required date from past 7 days
        todaysDateComponents.day = todaysDateComponents.day - day
        var requestDate = calendar.dateFromComponents(todaysDateComponents)

        for hour in 01...24 {
        //getting start and finish times
        var beginningOfDay = getDateForDaysAgo(day, hour: hour, minutes: 00)
        var endOfDay = getDateForDaysAgo(day, hour: hour, minutes: 59)

        //create a distanceRecord instance for each day
        var recordActivity = distanceRecord.init(startDate: beginningOfDay, endDate: endOfDay)

        //populate the dustanceRecord with data
        self.Pedometer.queryPedometerDataFromDate(beginningOfDay, toDate: endOfDay, withHandler: {activity, error in
            if (error != nil){
                NSLog(" \(error.localizedDescription)")
                ++errorCount
            }
            else{
                //*****TESTING
                ++count
                NSLog("\(count)")
                //add the step counting data
                recordActivity.stepCount = activity.numberOfSteps
                //add the distance data
                recordActivity.distance = activity.distance
                self.hourlyDistanceRecordArray.append(sigActivity)
            }
        })
        }
    }
    NSLog("Finished getting hours, \(count) records & \(errorCount) errors")
}

下面是调用viewDidLoad方法中更新标签的函数。

func getHighestHourInWeek() -> String {
    var itemsInArray = hourlyDistanceRecordArray.count
    NSLog("\(hourlyDistanceRecordArray.count)")
    var highestValue: Float = 0.0
    var highestDistanceRecord = distanceRecord(startDate: NSDate(), endDate: NSDate())
    for index in 0...itemsInArray {
        if hourlyDistanceRecordArray[index].distance.floatValue > highestValue {
            highestValue = hourlyDistanceRecordArray[index].distance.floatValue
            highestDistanceRecord = hourlyDistanceRecordArray[index]
        }
    }
    return highestDistanceRecord.distance.stringValue
}

我遇到的问题是getDistanceForEachHourInWeek()NSLog语句中的增量计数给了我一个数字,getHighestHourInWeek()NSLog中的array.count给了我另一个不同的通常更高的数字,并且都不等于我记录的168个记录期待并且它在每次运行它时给我的数字也不一致。我尝试使用调度队列解决它,但它没有帮助。

我的NSLog语句给我结果(缩短):

1
2
3
...
15
Finished getting hours, 15 records & 0 errors
16
17
18
...
192

任何人都可以帮我指出我哪里出错了吗?为什么代码在移动之前没有等待它完成for循环?

1 个答案:

答案 0 :(得分:0)

我使用NSNotification解决了这个问题。

在我的ModelController初始化程序中,我添加了

NSNotificationCenter.defaultCenter().addObserver(self, selector: "arrayPopulated", name: arrayPopulated, object: nil)

我修改了我的ModelController中的getDistanceForEachHourInWeek函数,以便检查计步器调用以查看我的数组中是否有尽可能多的记录(24 x 7 = 168)

self.Pedometer.queryPedometerDataFromDate(beginningOfDay, toDate: endOfDay, withHandler: {activity, error in
                    if (error != nil){
                        NSLog(" \(error.localizedDescription)")
                        NSLog("ERROR")
                        ++errorCount
                    }
                    else{
                        //XXXXXXXXTESTINGXXXXXXXX
                        ++count
                        tempActivity.stepCount = activity.numberOfSteps
                        //add the distance data
                        tempActivity.distance = activity.distance
                        //Append the tempActivity instance to myActivityArray
                        self.hourlyDistanceRecordArray.append(tempActivity)
                        if count == 168 {
                            NSNotificationCenter.defaultCenter().postNotificationName(self.arrayPopulated, object: self)
                        }
                    }
                })

然后在我的viewController的viewDidLoad函数中捕获了通知

NSNotificationCenter.defaultCenter().addObserver(self, selector: "actOnArrayPopulated", name: "arrayPopulated", object: nil)

并将所有标签更新放在函数

func actOnArrayPopulated() {
    NSLog("Notification received")
    self.updateScreen()
}

我的收到通知和我的屏幕正在更新但其进度

之间似乎仍然存在延迟