【问题标题】:Managing core data threads in iOS 7在 iOS 7 中管理核心数据线程
【发布时间】:2014-08-19 06:02:21
【问题描述】:

在主线程的目标 c 中使用核心数据会导致死锁。为了管理这个,我使用托管对象上下文,一个使用 NSMainQueueConcurrencyType,另一个使用 NSPrivateQueueConcurrencyType。这是代码-

 - (NSManagedObjectContext *)mainQueueContext
 {
  if (!_mainQueueContext) {
    _mainQueueContext = [[NSManagedObjectContext alloc]   initWithConcurrencyType:NSMainQueueConcurrencyType];
    _mainQueueContext.persistentStoreCoordinator = self.persistentStoreCoordinator;
   }

   return _mainQueueContext;
 }

- (NSManagedObjectContext *)privateQueueContext
{
  if (!_privateQueueContext) {
    _privateQueueContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
    _privateQueueContext.persistentStoreCoordinator =     self.persistentStoreCoordinator;
    }

 return _privateQueueContext;
}

我也设置了通知-

- (void)contextDidSavePrivateQueueContext:(NSNotification *)notification
{
  @synchronized(self) {
    [self.mainQueueContext performBlock:^{
        [self.mainQueueContext  mergeChangesFromContextDidSaveNotification:notification];
    }];
  }
}

- (void)contextDidSaveMainQueueContext:(NSNotification *)notification    
{
 @synchronized(self) {
    [self.privateQueueContext performBlock:^{
        [self.privateQueueContext     mergeChangesFromContextDidSaveNotification:notification];
    }];
  }
}


- (id)init
 {
  self = [super init];
  if (self) {
    [[NSNotificationCenter defaultCenter] addObserver:self   selector:@selector(contextDidSavePrivateQueueContext:)name:NSManagedObjectContextDidSaveNotification object:[self privateQueueContext]];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(contextDidSaveMainQueueContext:) name:NSManagedObjectContextDidSaveNotification object:[self mainQueueContext]];
   }
   return self;
 }

 - (void)dealloc
 {
 [[NSNotificationCenter defaultCenter] removeObserver:self];
 }

现在我的问题是从后台队列的核心数据中获取记录。我的获取记录的代码是-

 -(NSArray *)fetchNameForStr:(NSString *)str
 {
  NSManagedObjectContext *childContext=[CoreDataStore privateQueueContext];
  __block NSArray *array=nil;
  [childContext performBlock:^{
  NSFetchRequest *request = [[NSFetchRequest alloc] init];
  [request setEntity:[NSEntityDescription entityForName:@"Entity" inManagedObjectContext:childContext]];
  NSPredicate *predicate=[NSPredicate predicateWithFormat:@"(name=%@)", str];
  [request setPredicate:predicate];
  [request setResultType:NSDictionaryResultType];
  NSError *error = nil;
  array = [childContext executeFetchRequest:request error:&error];
  return array;

  }];
return dict;
}

上面的函数返回 nil,因为获取是异步执行的。如何将完成处理程序放入其中?如何获得可以从此函数返回的结果? 我以同样的方式将记录保存在核心数据中。这是否也会导致同步保存和获取的问题?

我陷入了这个核心数据线程问题。帮助我摆脱困境。

【问题讨论】:

  • 在您的函数中,您将返回一些任意对象dict。那是 nil,与您的 fetch 无关。
  • 是的,我知道。我想知道怎么控制?
  • 返回结果,而不是 nil 对象。呵呵。

标签: ios objective-c multithreading core-data ios7


【解决方案1】:

如果您使用异步请求获取结果的最简单方法 - 使用块作为参数并将返回类型更改为 void。并在块的末尾 - 使用结果调用参数块。像这样的:

typedef void (^ResultBlockType)(NSArray *resultArray, NSError *error);

- (void)fetchNameForStr:(NSString *)str resultBlock:(ResultBlockType)resultBlock {
        NSManagedObjectContext *childContext = [CoreDataStore privateQueueContext];
        __block NSArray *array = nil;
        [childContext performBlock:^{
         NSFetchRequest *request = [[NSFetchRequest alloc] init];
        [request setEntity:[NSEntityDescription entityForName:@"Entity" inManagedObjectContext:childContext]];
        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(name=%@)", str];
        [request setPredicate:predicate];
        [request setResultType:NSDictionaryResultType];
        NSError *error = nil;
        array = [childContext executeFetchRequest:request error:&error];
        resultBlock(array, error)

    }];
}

【讨论】:

    猜你喜欢
    • 2015-12-21
    • 1970-01-01
    • 1970-01-01
    • 2013-11-26
    • 1970-01-01
    • 2011-03-15
    • 1970-01-01
    • 2013-01-17
    相关资源
    最近更新 更多