【发布时间】:2014-05-10 14:10:06
【问题描述】:
我在下面有以下代码 sn-p,它在后台使用 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;
}
堆栈跟踪:
【问题讨论】:
-
可能与错误无关,但是为什么要使用外部
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{...});? IMO 这没有任何意义。您可以直接删除它,然后直接调用内联块中的代码。 -
同意@couchdeveloper。这看起来不错,除了将整个东西包装在 dispatch_async 中。
-
这是我尚未删除的旧设置中的剩余代码,我将编辑上面的内容以删除它。我知道这是一个多余的部分。那么在这种情况下,为什么我会收到我遇到的错误呢?
-
您是否更改了代码,或者只是问题?这看起来像是一个变量范围问题,但如果不知道您实际运行的是什么代码,就很难知道。
-
我刚刚删除了 dispatch_async 包装器。这真的没什么区别。最后还是同样的错误。
标签: objective-c parse-platform objective-c-blocks grand-central-dispatch