ios - EXC_BAD_INSTRUCTION 在 dispatch_get_current_queue()

标签 ios core-data objective-c-blocks grand-central-dispatch

我正在做一个使用核心数据的项目,据我所知,在核心数据线程中完成的任何事情都必须保留在该线程中。

我调用 API 来下载一些新闻项目,然后将它们加载到数据库中:

  [self.database.managedObjectContext performBlock:^{
    for (NSDictionary *itemInfo in result) {
      NSLog(@"%@", itemInfo);
      [Item createItemWithInfo:itemInfo inManagedObjectContext:self.database.managedObjectContext];
    }

    [self.database.managedObjectContext save:nil];
  }];

在我的创建方法中,除了在对象中设置所有数据外,我还有一个额外的调用来获取与相关新闻项目相关的图像:

+ (Item *)createItemWithInfo:(NSDictionary *)info inManagedObjectContext:(NSManagedObjectContext *)context {
  Item *item;

  NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Item"];
  request.predicate = [NSPredicate predicateWithFormat:@"itemId = %@", [info valueForKeyPath:@"News.id_contennoticias"]];
  NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"itemId" ascending:YES];
  request.sortDescriptors = [NSArray arrayWithObject:sortDescriptor];

  NSError *error = nil;
  NSArray *matches = [context executeFetchRequest:request error:&error];

  if (!matches || ([matches count] > 1)) {
    // handle error
  } else if ([matches count] == 0) {
    item = [NSEntityDescription insertNewObjectForEntityForName:@"Item" inManagedObjectContext:context];
    item.itemId = [NSNumber numberWithInteger:[[info valueForKeyPath:@"News.id_contennoticias"] integerValue] ];
    item.title = [info valueForKeyPath:@"News.titulo_contennoticias"];
    item.summary = [info valueForKeyPath:@"News.sumario_contennoticias"];
    item.content = [info valueForKeyPath:@"News.texto_contennoticias"];

    NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
    dateFormat.dateFormat = @"yyyy-MM-dd hh:mm:ss";
    NSDate *creationDate = [dateFormat dateFromString:[info valueForKeyPath:@"News.fechacre_contennoticias"]];
    item.creationDate = creationDate;

    dispatch_queue_t imageDownloadQueue = dispatch_queue_create("image downloader", NULL);
    dispatch_async(imageDownloadQueue, ^{
      NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@/files/imagenprincipal/%@", BASE_PATH, [info valueForKeyPath:@"News.imgprincipal"]]];
      NSData *imageData = [NSData dataWithContentsOfURL:url];
      dispatch_async(dispatch_get_current_queue(), ^{
        item.image = imageData;
      });
    });
  } else {
    item = [matches lastObject];
  }

  return item;  
}

关于这部分:

dispatch_async(dispatch_get_current_queue(), ^{
  item.image = imageData;
});

我遇到了错误,我的应用就在那里死掉了。它还表示 dispatch_get_current_queue() 在 iOS 6 中已弃用。

最佳答案

既然 dispatch_get_current_queue() 是从 imageDownloadQueue 的一个 block 中调用的,为什么不直接使用 imageDownloadQueue?如果您想在 moc 队列上运行它,请确保不要使用 dispatch_get_current_queue()

通常要小心使用 dispatch_get_current_queue()。引用 Apple 并发编程指南中的 Dispatch Queues 页面:

Use the dispatch_get_current_queue function for debugging purposes or to test the identity of the current queue.

关于ios - EXC_BAD_INSTRUCTION 在 dispatch_get_current_queue(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12592127/

相关文章:

iphone - 发送文本然后调用联系人 iPhone 应用程序

ios - 在 iOS 应用 [phonegap/cordova][Pushwoosh] 上将推送通知显示为警报消息

ios - 使用支持的 NSFetchedResultsController 展开/折叠 UITableView 部分

objective-c - Objective c - 取消 dealloc 中的操作

iphone - 在 Objective C 中使用 block 编程进行内存管理

iphone - self 保留在这个 Objective-C block 中吗?

objective-c - 拖动 UIImages 到选中区域

objective-c - UIScreen亮度超出最大值

ios - 核心数据 - 具有一对多关系的 sectionNameKeyPath

objective-c - 清空核心数据 NSSet(多个关系)