我得到了一个类似于刷新器的方法,它使用如下所示的GCD模式:
func getStepsForTheWeek() {
let concurrentQueue : dispatch_queue_t = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
dispatch_async(concurrentQueue, {
// Create an array of Days.
var days = [Day]()
dispatch_sync(concurrentQueue, {
print("first")
for day in 0...7 {
let date = self.getDate(day)
// Get the date the day after that day.
let endDate = self.getDateDayAfter(date)
// Create a Day.
var day = Day(date: date)
self.pedometer.queryPedometerDataFromDate(date, toDate: endDate, withHandler: {numberOfSteps, error in
print("fetching")
if error != nil {
print("There was an error requesting data from the pedometer: (error)")
} else {
day.steps = numberOfSteps!.numberOfSteps as Int
days.append(day)
}
})
}
})
dispatch_sync(dispatch_get_main_queue(), {
print("second")
self.historyViewController.days = days
self.historyViewController.reloadHistory()
})
})
}
当应用程序启动时,该方法按预期工作。但当应用程序在后台时,当我回到应用程序时,我得到了这个Observer,它再次调用该方法来刷新其内容。
NSNotificationCenter.defaultCenter().addObserver(self, selector: "appBecomeActive", name: UIApplicationWillEnterForegroundNotification, object: nil )
但每次我这样做时,第二个代码块都在第一个代码块之前运行。有什么帮助吗?
我认为您应该在计步器查询的完成处理程序中进行UI更新
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), {
self.pedometer.queryPedometerDataFromDate(date, toDate: endDate, withHandler: { numberOfSteps, error in
if error != nil {
print("There was an error requesting data from the pedometer: (error)")
} else {
let numberOfStepsThisDay = numberOfSteps?.numberOfSteps as! Int
day.steps = numberOfStepsThisDay
days.append(day)
}
dispatch_async(dispatch_get_main_queue(), {
self.historyViewController.days = self.days
self.historyViewController.reloadHistory()
})
})
})
如果方法的完成处理程序中有UI,您应该始终更新它,因为您不知道它是否可以是异步的(如果使用完成处理程序,通常会是异步的),如果其中除了计步器查询之外没有其他代码,您可能会删除外部dispatch_async
我解决了它。在查询中,我检查天数数组是否已填充(例如大小为8)。填充后应重新加载。我还删除了所有不必要的同步任务。现在干净多了。这比我想象的要简单。
func getStepsForTheWeek() {
// Create an array of Days.
var days = [Day]()
print("first")
// Fetch the total steps per day for 8 days (0 - 7).
for day in 0...7 {
// Get days date from today.
let date = self.getDate(day)
// Get the date the day after that day.
let endDate = self.getDateDayAfter(date)
// Create a Day.
var day = Day(date: date)
// Query the Pedometer for the total steps of that day.
self.pedometer.queryPedometerDataFromDate(date, toDate: endDate) {
(data, error) -> Void in
if(error == nil){
print("fetching")
day.steps = data!.numberOfSteps as Int
days.append(day)
if(days.count == 8){
dispatch_async(dispatch_get_main_queue(), { () -> Void in
print("finished")
self.historyViewController.days = days
self.historyViewController.reloadHistory()
})
}
}
}
}
}
感谢Fonix和咬牙切齿729。