假設我有幾個地址。我需要獲取循環中每個地址的座標。但獲取一個地址的座標需要一些時間。如何在一個循環中異步獲取座標?ios CLGeocoder。異步地理編碼
回答
您可以編寫一個例程,對可變數組中的單個地址進行地理編碼,然後調用自身來處理完成塊中的下一個地址。因此:
- (void)nextGeocodeRequest {
// if we're done, dp whatever you want
if ([self.addresses count] == 0) {
// do whatever you want when we're done (e.g. open maps)
return;
}
// if not, get the next address to geocode from NSMutableArray and
// remove it from list of addresses to process
NSString *address = self.addresses[0];
[self.addresses removeObjectAtIndex:0];
// geocode the address
CLGeocoder *geocoder = [[CLGeocoder alloc]init];
[geocoder geocodeAddressString:address completionHandler:^(NSArray *placemarks, NSError *error) {
// do whatever you want for the individual geocode process
// when all done, queue up the next geocode address
[self nextGeocodeRequest];
}];
}
或者,更復雜,你可以使用操作隊列:
- (void)geocodeAddresses:(NSArray <NSString *>*)addresses {
CLGeocoder *geocoder = [[CLGeocoder alloc]init];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
queue.maxConcurrentOperationCount = 1;
queue.name = @"com.domain.app.geocode";
NSOperation *finalCompletionOperation = [NSBlockOperation blockOperationWithBlock:^{
// do whatever you want when all done
NSLog(@"done");
}];
for (NSString *address in addresses) {
// create a block for the geocode request completion block
NSOperation *geocodeOperation = [[GeocodeOperation alloc] initWithGeocoder:geocoder Address:address geocodeCompletionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
if (error) {
NSLog(@"error = %@", error);
} else {
NSLog(@"placemarks = %@", placemarks);
}
}];
// The final completion block is contingent on the completion of this geocode request completion block
[finalCompletionOperation addDependency:geocodeOperation];
// let's queue the geocode request
[queue addOperation:geocodeOperation];
}
[queue addOperation:finalCompletionOperation];
}
其中,GeocodeOperation.h
:
#import "AsynchronousOperation.h"
@import CoreLocation;
NS_ASSUME_NONNULL_BEGIN
@interface GeocodeOperation : AsynchronousOperation
@property (readonly, nonatomic, copy) NSString *address;
- (instancetype)initWithGeocoder:(CLGeocoder *)geocoder Address:(NSString *)address geocodeCompletionHandler:(CLGeocodeCompletionHandler) geocodeCompletionHandler;
@end
NS_ASSUME_NONNULL_END
而且,GeocodeOperation.m
:
#import "GeocodeOperation.h"
@interface GeocodeOperation()
@property (nonatomic, strong) CLGeocoder *geocoder;
@property (nonatomic, copy, nonnull) NSString *address;
@property (nonatomic, copy) CLGeocodeCompletionHandler geocodeCompletionHandler;
@end
@implementation GeocodeOperation
- (instancetype)initWithGeocoder:(CLGeocoder *)geocoder Address:(NSString * _Nonnull)address geocodeCompletionHandler:(CLGeocodeCompletionHandler) geocodeCompletionHandler {
self = [super init];
if (self) {
self.geocoder = geocoder;
self.address = address;
self.geocodeCompletionHandler = geocodeCompletionHandler;
}
return self;
}
- (void)main {
[self.geocoder geocodeAddressString:self.address completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
self.geocodeCompletionHandler(placemarks, error);
[self completeOperation];
}];
}
- (void)cancel {
[self.geocoder cancelGeocode];
[super cancel];
}
@end
而AsynchronousOperation.h
:
@interface AsynchronousOperation : NSOperation
/// Complete the asynchronous operation.
///
/// This also triggers the necessary KVO to support asynchronous operations.
- (void)completeOperation;
@end
而且AsynchronousOperation.m
:
//
// AsynchronousOperation.m
//
#import "AsynchronousOperation.h"
@interface AsynchronousOperation()
@property (getter = isFinished, readwrite) BOOL finished;
@property (getter = isExecuting, readwrite) BOOL executing;
@end
@implementation AsynchronousOperation
@synthesize finished = _finished;
@synthesize executing = _executing;
- (instancetype)init {
self = [super init];
if (self) {
_finished = NO;
_executing = NO;
}
return self;
}
- (void)start {
if (self.isCancelled) {
if (!self.isFinished) self.finished = YES;
return;
}
self.executing = YES;
[self main];
}
- (void)completeOperation {
if (self.isExecuting) self.executing = NO;
if (!self.isFinished) self.finished = YES;
}
#pragma mark - NSOperation methods
- (BOOL)isAsynchronous {
return YES;
}
- (BOOL)isExecuting {
@synchronized(self) { return _executing; }
}
- (BOOL)isFinished {
@synchronized(self) { return _finished; }
}
- (void)setExecuting:(BOOL)executing {
[self willChangeValueForKey:@"isExecuting"];
@synchronized(self) { _executing = executing; }
[self didChangeValueForKey:@"isExecuting"];
}
- (void)setFinished:(BOOL)finished {
[self willChangeValueForKey:@"isFinished"];
@synchronized(self) { _finished = finished; }
[self didChangeValueForKey:@"isFinished"];
}
@end
awsome!拯救了我的一天! – SwingerDinger
@SingerDinger - 我不知道你是使用我的第一個例子還是我的第二個例子,但第二個例子並不是很正確,但我已經修復它以使用正確的異步操作。 – Rob
我已經使用過你的第二個實現並將其轉換成Swift 3.0。像魅力一樣工作。 – SwingerDinger
- 1. 處理CLGeocoder(iOS5)中的異步事件
- 2. 地理位置異步iOS
- 3. Google地理編碼器異步問題
- 4. 異步調用(特別是iOS的地理編碼)
- 5. CLGeocoder反地理編碼失敗,錯誤域= NSURLErrorDomain代碼= -1000 -
- 6. iOS:使用CLGeocoder與ReverseGeocoding進行比較Google地理編碼器API
- 7. 在使用CLGeocoder重複地理編碼之後kCLErrorDomain錯誤2
- 8. 使用CLGeocoder的轉發地理編碼示例
- 9. 使用CLGeocoder轉發地理編碼問題
- 10. CLGeocoder給定位置的反向地理編碼
- 11. CLGeocoder反向地理編碼數據後「返回」
- 12. CLGeocoder前進地理編碼倍數位置
- 13. 如何使用CLGeocoder反轉地理編碼大陸?
- 14. 地圖:反向地理編碼請求:jquery異步請求
- 15. 谷歌地圖地理編碼差異
- 16. 填充javascript數組與異步地理編碼功能
- 17. 在iOS中使用CLGeocoder進行前向地理編碼對於某些位置的地點返回null
- 18. 強制CLGeocoder塊代碼同步運行
- 19. GMaps JS地理編碼:使用異步地理編碼功能來傳遞變量?
- 20. CLGeocoder多地址?
- 21. iOS CoreLocation CLGeocoder提供不完整的英國郵政編碼
- 22. iOS上的正向地理編碼
- 23. IOS谷歌地理編碼API
- 24. 谷歌地理編碼和distancematrix差異
- 25. 對CLGeocoder類方法進行反向地理編碼的方法感到困惑
- 26. 異步編碼斯卡拉
- 27. iPhone JSON異步編碼
- 28. 當Android和iOS不是異步時,如何處理UWP異步?
- 29. 反向地理編碼的地方本地化ios
- 30. Ios的火力地堡異步的LogIn
的 「怎麼辦」 的問題的數量有所增加。如果你還沒有找到任何你仍然可以問的問題,但請至少在網上搜索。 –