运行 组中并发操作,但 运行 然后 运行 批次这些操作串行
Run operations in a group concurrently, but run then run batches of these operations serially
将这些带入枚举循环。他们枚举对象数组并保存它们。我希望这些中的每一个同时 运行,但是,我想等到所有 categoriesMainToSave
return,然后再开始 categoriesSubToSave
批处理。
// Save all the categories
[categoriesMainToSave enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
CategoryMain* main = (CategoryMain*)obj;
[[BFClientAPI sharedAPI] createCategoryMain:main withSuccess:^{
} failure:^(NSError *error) {
NSLog(@"error = %@",error);
}];
}];
[categoriesSubToSave enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
CategorySub* sub = (CategorySub*)obj;
[[BFClientAPI sharedAPI] createCategorySub:sub withSuccess:^{
} failure:^(NSError *error) {
NSLog(@"error = %@",error);
}];
}];
我开始尝试调度组:
dispatch_group_t groupMain = dispatch_group_create();
[categoriesMainToSave enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
dispatch_group_enter(groupMain);
CategoryMain* main = (CategoryMain*)obj;
[[BFClientAPI sharedAPI] createCategoryMain:main withSuccess:^{
dispatch_group_leave(groupMain);
} failure:^(NSError *error) {
NSLog(@"error = %@",error);
dispatch_group_leave(groupMain);
}];
}];
dispatch_group_notify(groupMain,dispatch_get_main_queue(),^{
// Repeat dispatch_group pattern with categoriesSubToSave here
});
但后来我在 dispatch_group_notify
中创建了一个嵌套效果。还有其他方法吗?
尝试使用枚举选项的方法:
- (void)enumerateObjectsWithOptions:(NSEnumerationOptions)opts
usingBlock:(void (^)(id obj,
NSUInteger idx,
BOOL *stop))block
来自文档:
指定 Block 枚举应该是并发的。
调用顺序不确定且未定义;这个标志是一个提示,在某些情况下可能会被实现忽略; Block 的代码必须对并发调用是安全的。
UPD
如果createCategoryMain是并发操作。您需要同步许多异步操作。您可以使用 NSOperation 和 NSOperationQueue。操作让操作之间产生依赖关系。您可以创建操作列表,这些操作将从 categoriesMainToSave(第一组)初始化类别,以及将从 categoriesSubToSave(第二组)初始化类别的操作列表。然后您可以在第二组和第一组的操作之间建立依赖关系。然后将这些操作添加到 NSOperationsQueue 中。但我认为,现在你有非常简单的解决方案。
使用调度组是一个很好的解决方案。如果您不想将您的 categoriesSubToSave
作品嵌套在 dispatch_group_notify
块中,您可以使用 dispatch_group_wait
代替:
dispatch_group_t group = dispatch_group_create();
for (CategoryMain *main in categoriesMainToSave) {
dispatch_group_enter(group);
[[BFClientAPI sharedAPI] createCategoryMain:main withSuccess:^{
dispatch_group_leave(group);
} failure:^(NSError *error) {
NSLog(@"error = %@",error);
dispatch_group_leave(group);
}];
}
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
// All mains are now saved or failed.
for (CategorySub *sub in categoriesMainToSave) {
dispatch_group_enter(group);
[[BFClientAPI sharedAPI] createCategorySub:sub withSuccess:^{
dispatch_group_leave(group);
} failure:^(NSError *error) {
NSLog(@"error = %@",error);
dispatch_group_leave(group);
}];
}
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
// All subs are now saved or failed.
但是,如果这段代码在主线程上运行,这是一个非常糟糕的主意。如果您从主线程启动保存,或者从另一个线程启动保存,您应该使用 dispatch_group_notify
。
将这些带入枚举循环。他们枚举对象数组并保存它们。我希望这些中的每一个同时 运行,但是,我想等到所有 categoriesMainToSave
return,然后再开始 categoriesSubToSave
批处理。
// Save all the categories
[categoriesMainToSave enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
CategoryMain* main = (CategoryMain*)obj;
[[BFClientAPI sharedAPI] createCategoryMain:main withSuccess:^{
} failure:^(NSError *error) {
NSLog(@"error = %@",error);
}];
}];
[categoriesSubToSave enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
CategorySub* sub = (CategorySub*)obj;
[[BFClientAPI sharedAPI] createCategorySub:sub withSuccess:^{
} failure:^(NSError *error) {
NSLog(@"error = %@",error);
}];
}];
我开始尝试调度组:
dispatch_group_t groupMain = dispatch_group_create();
[categoriesMainToSave enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
dispatch_group_enter(groupMain);
CategoryMain* main = (CategoryMain*)obj;
[[BFClientAPI sharedAPI] createCategoryMain:main withSuccess:^{
dispatch_group_leave(groupMain);
} failure:^(NSError *error) {
NSLog(@"error = %@",error);
dispatch_group_leave(groupMain);
}];
}];
dispatch_group_notify(groupMain,dispatch_get_main_queue(),^{
// Repeat dispatch_group pattern with categoriesSubToSave here
});
但后来我在 dispatch_group_notify
中创建了一个嵌套效果。还有其他方法吗?
尝试使用枚举选项的方法:
- (void)enumerateObjectsWithOptions:(NSEnumerationOptions)opts
usingBlock:(void (^)(id obj,
NSUInteger idx,
BOOL *stop))block
来自文档:
指定 Block 枚举应该是并发的。
调用顺序不确定且未定义;这个标志是一个提示,在某些情况下可能会被实现忽略; Block 的代码必须对并发调用是安全的。
UPD
如果createCategoryMain是并发操作。您需要同步许多异步操作。您可以使用 NSOperation 和 NSOperationQueue。操作让操作之间产生依赖关系。您可以创建操作列表,这些操作将从 categoriesMainToSave(第一组)初始化类别,以及将从 categoriesSubToSave(第二组)初始化类别的操作列表。然后您可以在第二组和第一组的操作之间建立依赖关系。然后将这些操作添加到 NSOperationsQueue 中。但我认为,现在你有非常简单的解决方案。
使用调度组是一个很好的解决方案。如果您不想将您的 categoriesSubToSave
作品嵌套在 dispatch_group_notify
块中,您可以使用 dispatch_group_wait
代替:
dispatch_group_t group = dispatch_group_create();
for (CategoryMain *main in categoriesMainToSave) {
dispatch_group_enter(group);
[[BFClientAPI sharedAPI] createCategoryMain:main withSuccess:^{
dispatch_group_leave(group);
} failure:^(NSError *error) {
NSLog(@"error = %@",error);
dispatch_group_leave(group);
}];
}
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
// All mains are now saved or failed.
for (CategorySub *sub in categoriesMainToSave) {
dispatch_group_enter(group);
[[BFClientAPI sharedAPI] createCategorySub:sub withSuccess:^{
dispatch_group_leave(group);
} failure:^(NSError *error) {
NSLog(@"error = %@",error);
dispatch_group_leave(group);
}];
}
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
// All subs are now saved or failed.
但是,如果这段代码在主线程上运行,这是一个非常糟糕的主意。如果您从主线程启动保存,或者从另一个线程启动保存,您应该使用 dispatch_group_notify
。