一次)单例冻结/锁定在目标c中

这行代码在位于实现NSManagedObject的自定义托管对象内的awakeFromFetch方法中被调用。 这条线特别是打电话给我的单身网络管理员类叫做sharedManager

[self setSync:(![[WKNetworkManager sharedManager] objectHasPendingRequests:self.objectID]) ];

dispatch_once块将按如下所示命中。 请注意,它是以一种很好的方式实现的,如下所示:

在这里输入图像描述

然后调用dispatch_once调用once.h,然后在高亮显示的行上将其冻结:

dipatch_once更深

这是堆栈跟踪:

堆栈跟踪

所有这些都在尝试加载先前保存的网络队列文件时发生。 应用程序完全关闭以保存,然后再次启动,然后发生冻结/锁定。

我甚至试图用这个代码来解决这个问题,正如这里所建议的那样,它不起作用。 但改变这可能无关紧要,因为我的原始dispatch_once代码很长一段时间工作得很好。 只是在这种特殊情况下。

if ([NSThread isMainThread]) 
{
    dispatch_once(&onceToken, ^{
    stack = [[KACoreDataStack alloc] init];});
} 
else 
{
    dispatch_sync(dispatch_get_main_queue(), ^{
    dispatch_once(&onceToken, ^{
    stack = [[KACoreDataStack alloc] init];});
});
}

到目前为止,这些是我解决这类问题的来源:

  • 代码执行停止使用线程安全的Singleton初始化代码
  • http://cocoasamurai.blogspot.jp/2011/04/singletons-your-doing-them-wrong.html
  • http://www.raywenderlich.com/4295/multithreading-and-grand-central-dispatch-on-ios-for-beginners-tutorial
  • IOS的单身类崩溃我的应用程序
  • http://benalpert.com/2014/04/02/dispatch-once-initialization-on-the-main-thread.html
  • http://www.bignerdranch.com/blog/dispatch_once-upon-a-time/
  • 谢谢你的帮助!


    该死的儿子,这是一个很好的问题 - 问。

    这里的问题是对dispatch_once的递归调用会死锁。 如果你需要确切的细节,你可以在这里找到他们的来源。 所以你需要重写以避免这种情况。

    我的意见是,有任何导致此-loadQueueFromDisk调用的结构性失误。 您绝对不希望做任何可能无限制的执行时间,例如在dispatch_once从磁盘上卸载和加载某些内容。 你想要做的是创建一个可寻址的单身人士并退出的绝对最小值。 然后,给它一个“初始化”的内部状态,并将磁盘加载的东西发送到某个非阻塞队列中。 这样,所有不依赖于从磁盘加载的东西都可以继续,并且所有依赖于从磁盘加载的东西都可以将其自身添加到加载磁盘的队列中,或者每隔几百毫秒检查一次以查看如果它处于“初始化”状态,或者沿着这些线路。


    感谢alexcurylo的帮助,排队loadFromDisk作业解决了这个问题。 为了让人们不会感到困惑,恰好在下面的代码中,我排队等待从磁盘加载数组(作为用户请求的保存队列)的作业。 您可能正在排队任何作业,例如加载图像/等。我的sharedManager类中的以下代码(其中来自磁盘的加载被调用)起作用,如下所示:

    -(void) loadQueueFromFileByQueueing
    {
      //Create a Queue
      /* Note that fileStrQueue should be added to the .h file as NSOperationQueue *fileStrQueue;*/
      fileStrQueue = [[NSOperationQueue alloc] init];
    
      //Create an  operation which will invoke method loadQueueFromDisk
      NSInvocationOperation * operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(loadQueueFromDisk) object:nil];
    
      //Add this operation to the queue
      [fileStrQueue addOperation:operation];
    
      //Releasing the above operation as it is already retained by the queue.
      // [operation release]; // If you are using ARC, this won't be necessary
    }
    
    链接地址: http://www.djcxy.com/p/78851.html

    上一篇: once) singleton freezes / locks in objective c

    下一篇: Create singleton using GCD's dispatch