下面我有以下代码片段,它们在后台使用PFQueues从Parse获取数据并返回数据和状态。该结构基于等待dispatch_group_t通知它已完成所有输入的组。不幸的是dispatch_group_notify(downloadGroup, dispatch_get_main_queue(), ^{
在完成块调用dispatch_group_leave之前调用。在任何完成块上调用dispatch_group_leave()时,将抛出EXC_BAD_INSTRUCTION。我已在下面附上了一张图片,说明了指令错误。有没有人知道我做错了什么,或者Parse有些烦恼阻止我使用这种方法?
- (void)downloadAndCacheObjectsWithCompletion:(void (^)(NSError *))callback
{
__block NSError *downloadError1;
__block NSError *downloadError2;
__block NSError *downloadError3;
__block NSError *downloadError4;
NSLog(@"%@", NSStringFromSelector(_cmd));
dispatch_group_t downloadGroup = dispatch_group_create();
dispatch_group_enter(downloadGroup);
[self fetchDataWithCompletion:^(NSArray *artwork, NSError *error) {
downloadError1 = error;
dispatch_group_leave(downloadGroup);
}];
dispatch_group_enter(downloadGroup);
[self fetchDataWithCompletion:^(NSArray *artworkPhotos, NSError *error) {
downloadError2 = error;
dispatch_group_leave(downloadGroup);
}];
dispatch_group_enter(downloadGroup);
[self fetchDataWithCompletion:^(NSArray *artists, NSError *error) {
downloadError3 = error;
dispatch_group_leave(downloadGroup);
}];
dispatch_group_enter(downloadGroup);
[self fetchDataWithCompletion:^(NSArray *badges, NSError *error) {
downloadError4 = error;
dispatch_group_leave(downloadGroup);
}];
dispatch_group_notify(downloadGroup, dispatch_get_main_queue(), ^{
NSError *returnError;
if (downloadError1 || downloadError2 || downloadError3 || downloadError4) {
returnError = [[NSError alloc] initWithDomain:@"ParseFactory" code:-1 userInfo:@{NSLocalizedDescriptionKey: @"There was an error retrieving the content"}];
}
if (callback) {
callback(returnError);
}
});
}
- (void)fetchDataWithCompletion:(void(^)(NSArray *data, NSError *error))callback
{
NSLog(@"Fetching Data");
if ([self.cachedData objectForKey:kDataClassName]) {
if (callback) {
callback([self.cachedData objectForKey:kDataClassName], nil);
}
return;
}
PFQuery *dataQueue = [PFQuery queryWithClassName:kDataClassName];
dataQueue.cachePolicy = kPFCachePolicyCacheThenNetwork;
[dataQueue findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
[self.cachedData setObject:objects forKey:kDataClassName];
} else {
NSLog(@"Fetching Data Error: %@", error);
}
if (callback) {
callback(objects, error);
}
}];
}
上面列出的下载过程是从AppDelegate中调用的
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//Register PFObject subclasses
[Data registerSubclass];
[Parse setApplicationId:@"appkey" clientKey:@"clientkey"];
[[ParseFactory sharedInstance] downloadAndCacheObjectsWithCompletion:^(NSError *error) {
}];
return YES;
}
堆栈跟踪:
答案 0 :(得分:3)
您看到的错误表示您的程序调用{{1}}次数太多。重现它是微不足道的。我用这个程序复制了它:
dispatch_group_leave
因此,我推断您的int main(int argc, const char * argv[])
{
@autoreleasepool {
dispatch_group_t group = dispatch_group_create();
dispatch_group_leave(group);
}
return 0;
}
方法不止一次调用其完成块。如果您无法弄清楚原因,请编辑您的问题以包含该方法的源代码(以及任何相关的方法或声明)。
答案 1 :(得分:0)
我来晚了,但很明显你的问题来自kPFCachePolicyCacheThenNetwork
。
Parse将调用完成块两次,一次使用缓存数据(即使是第一次),一次使用下载数据...因此,dispatch_group_leave
将被调用为dispatch_group_enter
的两倍。