enumerateObjectsUsingBlock 和完成在一起
enumerateObjectsUsingBlock and completion together
我有这样的情况,我正在使用 enumerateObjectsUsingBlock 迭代我的数组对象,我需要等待迭代完成然后它应该执行进一步的代码,我该如何实现这个,或者如果我应该使用任何替代方法,下面是我的代码
[arrPendingQueue enumerateObjectsUsingBlock:^(PendingQueues *obj, NSUInteger idx, BOOL *stop) {
//Fetch static google map based on coordinates
[self generateMapImage:obj.postObj completion:^(UIImage *image) {
NSString *path = [NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES).firstObject stringByAppendingPathComponent:@"camera"];
NSString *resultPath = [path stringByAppendingPathComponent:[NSString stringWithFormat:@"map_%f.jpg",[[Constants getSystemDateInLocalTimeZone] timeIntervalSince1970]]];
[[NSFileManager defaultManager] createFileAtPath:resultPath contents:UIImageJPEGRepresentation(image, 1.0) attributes:nil];
postObj.imagepath = [@"camera" stringByAppendingPathComponent:[resultPath lastPathComponent]];
[DataManager saveObject:postObj];
}];
//After the completion I want to upload the data here to server
});
基本上,我正在尝试从函数 generateMapImage
中的坐标下载静态 google 地图,我希望循环等到完成调用..
为此我尝试使用 dispatch_semaphore_create
like
[arrPendingQueue enumerateObjectsUsingBlock:^(PendingQueues *obj, NSUInteger idx, BOOL *stop) {
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
[self generateMapImage:obj.postObj completion:^(UIImage *image) {
dispatch_semaphore_signal(semaphore);
}];
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
});
但它不工作它不等待,并在完成之前执行代码。
如何解决,求助
谢谢。
要排队执行一系列 a 块,您可以简单地在旧块的完成处理程序中启动新块:
NSEnumerator *objectEnum = [arrPendingQueue objectEnumerator];
__block void (^handler) ();
handler = ^(UIImage *image)
{
// Handle image
object = [objectEnum nextObject];
if( object == nil )
{
// completion of all operations
}
else
{
// Start next operation
[self generateMapImage:object.postObj completion:handler];
}
};
[self generateMapImage:obj.postObj completion:handler];
}
更经典或优雅的方法是使用 Y-combinator。但没有必要。请记住,局部作用域变量在失去作用域时会被清除。 handler
不保留。所以也许你必须把它放到一个ivar中。
不过,我看到-generateMapImage:completion
是你写的。我看不到内容,但是如果您在那里进行异步调用并且可以设置用于调用的队列,只需将其设置为串行队列即可。在这种情况下,您的请求将自动串行执行。
我有这样的情况,我正在使用 enumerateObjectsUsingBlock 迭代我的数组对象,我需要等待迭代完成然后它应该执行进一步的代码,我该如何实现这个,或者如果我应该使用任何替代方法,下面是我的代码
[arrPendingQueue enumerateObjectsUsingBlock:^(PendingQueues *obj, NSUInteger idx, BOOL *stop) {
//Fetch static google map based on coordinates
[self generateMapImage:obj.postObj completion:^(UIImage *image) {
NSString *path = [NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES).firstObject stringByAppendingPathComponent:@"camera"];
NSString *resultPath = [path stringByAppendingPathComponent:[NSString stringWithFormat:@"map_%f.jpg",[[Constants getSystemDateInLocalTimeZone] timeIntervalSince1970]]];
[[NSFileManager defaultManager] createFileAtPath:resultPath contents:UIImageJPEGRepresentation(image, 1.0) attributes:nil];
postObj.imagepath = [@"camera" stringByAppendingPathComponent:[resultPath lastPathComponent]];
[DataManager saveObject:postObj];
}];
//After the completion I want to upload the data here to server
});
基本上,我正在尝试从函数 generateMapImage
中的坐标下载静态 google 地图,我希望循环等到完成调用..
为此我尝试使用 dispatch_semaphore_create
like
[arrPendingQueue enumerateObjectsUsingBlock:^(PendingQueues *obj, NSUInteger idx, BOOL *stop) {
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
[self generateMapImage:obj.postObj completion:^(UIImage *image) {
dispatch_semaphore_signal(semaphore);
}];
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
});
但它不工作它不等待,并在完成之前执行代码。
如何解决,求助
谢谢。
要排队执行一系列 a 块,您可以简单地在旧块的完成处理程序中启动新块:
NSEnumerator *objectEnum = [arrPendingQueue objectEnumerator];
__block void (^handler) ();
handler = ^(UIImage *image)
{
// Handle image
object = [objectEnum nextObject];
if( object == nil )
{
// completion of all operations
}
else
{
// Start next operation
[self generateMapImage:object.postObj completion:handler];
}
};
[self generateMapImage:obj.postObj completion:handler];
}
更经典或优雅的方法是使用 Y-combinator。但没有必要。请记住,局部作用域变量在失去作用域时会被清除。 handler
不保留。所以也许你必须把它放到一个ivar中。
不过,我看到-generateMapImage:completion
是你写的。我看不到内容,但是如果您在那里进行异步调用并且可以设置用于调用的队列,只需将其设置为串行队列即可。在这种情况下,您的请求将自动串行执行。