2014-02-27 43 views
0

我想從座標中找到用戶的位置以保存到我的數據庫中。塊直到反向地址碼已經返回

查找我正在使用的位置名稱reverseGeocode。然而,由於它是一個塊方法,我的self.locationName將返回(並保存爲零)到數據庫中。所以我試圖找到問題的解決方案,並嘗試使用信號量將以下解決方案放在一起嘗試並阻止,直到我找到可以保存的位置名稱,但應用程序僅在按下保存按鈕時掛起。我是否應該以這種方式解決這個問題,還是有更好的方法?

dispatch_semaphore_t semaphore; 

- (void)reverseGeocode:(CLLocation *)location { 
    CLGeocoder *geocoder = [[CLGeocoder alloc] init]; 
    [geocoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks,     NSError *error) { 

    NSLog(@"Finding address"); 
    if (error) { 
    NSLog(@"Error %@", error.description); 
    } else { 
    CLPlacemark *placemark = [placemarks lastObject]; 
    self.locationName = [NSString stringWithFormat:@"%@", ABCreateStringWithAddressDictionary(placemark.addressDictionary, NO)]; 
    dispatch_semaphore_signal(semaphore);   
      } 
    }]; 
    } 



-(NSString *)findLocation:(CLLocation *)startingLocation 
{ 
semaphore = dispatch_semaphore_create(0); 
[self reverseGeocode:startingLocation]; 
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); //should maybe timeout 
return self.locationName; 
} 
+5

重做你的代碼,以便代替'findLocation:'返回一個字符串,讓它代替一個塊,然後你可以調用你的反向地理編碼方法完成。該塊將處理保存數據庫中的位置名稱。 – Gavin

+3

爲了擴展Gavin的答案,幾乎從來沒有正確的方法來進行同步網絡(或其他長時間運行的進程)調用。 –

+0

謝謝你的建議@Gavin。當我開始思考信號量時,我知道我正在嘗試創建一個解決方法! – Sarah92

回答

3

您正在考慮這一切都是錯誤的。這不是異步代碼的工作方式。在不是阻止,直到代碼返回。只需啓動代碼即可啓動反向地理編碼,然後完成。現在,當反向地理編碼完成時,它會回叫您,您可以使用返回的信息執行任何操作。這是完成處理程序的全部要點:它只有在反向地理編碼完成後才能運行。

只是擺脫信號量,讓事情異步發生。這裏是沒有輔助方法,一個完整的例子:

CLLocation* loc = userLocation.location; 
[geo reverseGeocodeLocation:loc 
      completionHandler:^(NSArray *placemarks, NSError *error) 
    { 
     if (placemarks) { 
      CLPlacemark* p = [placemarks objectAtIndex:0]; 
      NSLog(@"%@", p.addressDictionary); // do something with address 
     } 
    }]; 

正如你已經被告知,如果你真的想從另一個方法調用這個,然後做進一步的東西,然後通過一個塊這種方法和呼叫完成處理程序中的塊。這意味着您傳遞的代碼塊是在地理編碼完成時運行的代碼,這正是您想要的 - 沒有信號量並且不凍結應用程序。

凍結應用程序是不好的形式,WatchDog會殺死你的應用程序,如果你這樣做太久了。只是不要這樣做。

+0

什麼「完成」「它回叫你」的意思是? – Sarah92

+0

「完成」意味着停止。您的代碼結束。現在界面不會凍結。 「它回叫你」意味着最後運行的完成處理程序(也許在你開始處理後很長一段時間)。 – matt

+0

但我如何知道完成處理程序在我嘗試保存locationName之前運行?這段代碼也在我從中調用它的數據庫類的一個單獨的類中。所以我只想確保我有位置名稱並可以保存它。在我繼續之前,我不想等待「有時」發生。 – Sarah92