2016-05-06 3 views
3

comme le code ci-dessous, quand je veux retourner un podomètre par une méthode pour une certaine connivence, mais la méthode retournée plus tôt que les données soient récupérées. problème de concurrence. Comment est-ce que je pourrais renvoyer les données d'une manière correcte pour l'usage futur? ThxiOS Problème de concurrence: méthode retournée avant d'avoir les données du podomètre

func queryPedometerTodayTotalData() -> Int { 
    var pedometerDataOfToday: CMPedometerData? 
     self.queryPedometerDataFromDate(NSDate.today()!, toDate: NSDate(), withHandler: { (pedometerData, error) in 
      pedometerDataOfToday = pedometerData! 
      print("this print after got data in a background thread:\(pedometerDataOfToday)") 
     }) 
     print("This should print before last print, and there haven't got the data now: \(pedometerDataOfToday)") 
    return pedometerDataOfToday 
} 

Répondre

2

Vous avez raison sur le fait qu'il s'agit d'un problème de simultanéité. Vous devriez utiliser le résultat dans le gestionnaire du queryPedometerDataFromDate. Une façon d'y parvenir serait d'utiliser un bloc d'achèvement pour la méthode queryPedometerTodayTotalData au lieu d'avoir le retourner une valeur, comme ceci:

func queryPedometerTodayTotalData(completion:((CMPedometerData?)->())) { 
    var pedometerDataOfToday: CMPedometerData? 
    self.queryPedometerDataFromDate(NSDate.today()!, toDate: NSDate(), withHandler: { (pedometerData, error) in 
     pedometerDataOfToday = pedometerData! 
     completion(pedometerData) 
    }) 
} 

func testQueryPedometerTodayTotalData() { 
    self.queryPedometerTodayTotalData { (data) in 
     print(data) 
    } 
} 
+0

thx.I a fait, il pourrait imprimer correctement les données, mais comment pourrais-je à retourner les données? 'func testQueryPedometerTodayTotalData() -> CMPedometerData { var aujourd'huiData: CMPedometerData? self.queryPedometerTodayTotalData {(données) dans todayData = données } retourner aujourd'huiData! } '
Cela va se bloquer à nouveau –

+0

Vous ne pouvez pas le retourner car il est asynchrone. Vous l'utilisez dans le bloc d'achèvement. Au lieu d'imprimer les données, vous pouvez faire ce que vous voulez avec. – marosoaie

+0

Alors appréciez. J'utilise une autre solution pour le traiter. Mais je veux vraiment savoir pourquoi je n'ai pas pu obtenir ou retourner un résultat asynchrone? J'ai utilisé une variable d'instance pour enregistrer le résultat dans le bloc et revenir, pourriez-vous expliquer pourquoi cela ne fonctionne pas, encore –

0

C'est un problème de concurrence. queryPedometerDataFromDate est une méthode asynchrone. il exécute le bloc d'achèvement à chaque fois que iOS le considère (ce qui se produit généralement après avoir récupéré les données), c'est pourquoi la deuxième ligne d'impression s'imprime en premier et ne renvoie pas le résultat.

Vous devez utiliser le pedometerData du bloc d'achèvement dans le bloc d'achèvement, ou appeler une méthode/délégué qui gérera le résultat du bloc d'achèvement.