说明: 在我的Xcode项目中,我有3个数据存储区:SFGroupsItemStore,SFFeedsItemStore,SFQuestsItemStore。所有这个类都是我的自定义类的子类,并且都是单例。 我在下一个控制器中使用的每个类:SFGroupsListViewController SFFeedsListViewController,SFQuestsListViewController。所有这个类都有方法:-downloadItems
问题: 我想创建一个控制器SFHomeViewController,它将呈现所有3个数据存储混合的表。 为了解决这个问题,我想创建聚合器SFHomeItemStore,也是单例,我希望这个类有方法-downloadItems。
所以,我已经完成了,SF HomeItemStore中有-downloadIItems的实现
1步:
- (NSArray *)downloadItemsFrom:(int32_t)from withLimit:(int)limit andDirection:(NSString *)direction{
NSArray *groupsItems = [[SFGroupsItemStore shared] downloadItems];
NSArray *feedsItems = [[SFFeedsItemStore shared] downloadItems];
NSArray *questsItems = [[SFQuestsItemStore shared] downloadItems];
NSMutableArray *mixedArray = [NSMutableArray array];
[mixedArray addObjectsFromArray:groupsItems];
[mixedArray addObjectsFromArray:feedsItems];
[mixedArray addObjectsFromArray:questsItems];
NSArray *sortedArray = [mixedArray sortedArrayUsingDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"createdAt" ascending:NO]]];
return sortedArray;
}
这项工作对我来说很好。
2步: 但我不喜欢方法调用-downloadItems顺序,为什么调用这个方法我需要花更多的时间 但如果我添加GCD我有问题, 现在实现方法-downloadItems是
- (NSArray *)downloadItemsFrom:(int32_t)from withLimit:(int)limit andDirection:(NSString *)direction{
__block NSArray *sortedArray = nil;
__block NSArray *groupsItems;
__block NSArray *feedsItems;
__block NSArray *questsItems;
dispatch_group_t groupedTask = dispatch_group_create();
dispatch_queue_t globalQueue = dispatch_get_global_queue( 0, 0 );
dispatch_group_async( groupedTask, globalQueue, ^{
groupsItems = [[SFGroupsItemStore shared] downloadItems];
} );
dispatch_group_async( groupedTask, globalQueue, ^{
feedsItems = [[SFFeedsItemStore shared] downloadItems];
} );
dispatch_group_async( groupedTask, globalQueue, ^{
questsItems = [[SFQuestsItemStore shared] downloadItems];
} );
dispatch_group_notify( groupedTask, globalQueue, ^{
NSMutableArray *mixedArray = [NSMutableArray array];
[mixedArray addObjectsFromArray:groupsItems];
[mixedArray addObjectsFromArray:feedsItems];
[mixedArray addObjectsFromArray:questsItems];
sortedArray = [mixedArray sortedArrayUsingDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"createdAt" ascending:NO]]];
} );
return sortedArray;
}
问题是,无论dispatch_group_notify如何,方法返回结果以及为什么数组sortedArray为空
所以,我的问题是: 我怎么做才能在dispatch_group_notify函数结束后返回结果?
答案 0 :(得分:0)
您有两种选择:
dispatch_group_wait
。NSArray
。来自文档:
同步等待先前提交的块对象 完成;如果块未在指定之前完成,则返回 超时时间已过。
你的方法看起来像这样:
- (NSArray *)downloadItemsFrom:(int32_t)from withLimit:(int)limit andDirection:(NSString *)direction{
// ...
dispatch_group_async( groupedTask, globalQueue, ^{
groupsItems = [[SFGroupsItemStore shared] downloadItems];
} );
// ...
dispatch_group_wait(groupedTask, DISPATCH_TIME_FOREVER);
NSMutableArray *mixedArray = [NSMutableArray array];
[mixedArray addObjectsFromArray:groupsItems];
[mixedArray addObjectsFromArray:feedsItems];
[mixedArray addObjectsFromArray:questsItems];
sortedArray = [mixedArray sortedArrayUsingDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"createdAt" ascending:NO]]];
return sortedArray;
}
这是我喜欢的方法。
您需要更改方法签名,以便将完成处理程序作为新参数,并返回void
而不是NSArray
。使用此方法,您仍然使用dispatch_group_notify
。
它看起来像这样:
- (void)downloadItemsFrom:(int32_t)from
withLimit:(int)limit
direction:(NSString *)direction
andCompletionHandler:(void (^)(NSArray*))completionHandler
{
// ...
dispatch_group_async( groupedTask, globalQueue, ^{
groupsItems = [[SFGroupsItemStore shared] downloadItems];
} );
// ...
dispatch_group_notify( groupedTask, globalQueue, ^{
NSMutableArray *mixedArray = [NSMutableArray array];
[mixedArray addObjectsFromArray:groupsItems];
[mixedArray addObjectsFromArray:feedsItems];
[mixedArray addObjectsFromArray:questsItems];
sortedArray = [mixedArray sortedArrayUsingDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"createdAt" ascending:NO]]];
completionHandler(sortedArray);
} );
}
现在调用它看起来像:
[object downloadItemsFrom:...
withLimit:...
diretion:...
andCompletionHandler:^(NSArray *items)
{
}];