Эта строка кода вызывается в моем методе awakeFromFetch
, расположенном внутри настраиваемого управляемого объекта, который реализует NSManagedObject
. Эта строка, в частности, вызывает звонок в мой однопользовательский сетевой менеджер, называемый sharedManager
.Отправка один раз (dispatch_once) singleton freezes/locks в объекте c
[self setSync:(![[WKNetworkManager sharedManager] objectHasPendingRequests:self.objectID]) ];
Блок dispatch_once будет удален, как показано ниже. Обратите внимание на то, что она реализуется в хорошем смысле, как это показано here:
Вызов dispatch_once затем переходит к once.h и здесь она замерзает прямо на выделенной линии:
Вот трассировки стека:
Все это происходит при попытке загрузить ранее сохраненный файл сетевой очереди. Приложение полностью закрывается для сохранения, а затем запускается снова, а затем происходит это замораживание/блокировка.
Я даже попытался использовать этот код вместо этого, чтобы решить проблему, как предлагается here, и это не сработало. Но изменение этого, вероятно, не имеет значения, так как мой оригинальный код 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];});
});
}
До сих пор, это мои источники для устранения неполадок такого рода проблемы:
- Code execution stops on using thread safe Singleton initialization code
- 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 singleton class crashes my app
- http://benalpert.com/2014/04/02/dispatch-once-initialization-on-the-main-thread.html
- http://www.bignerdranch.com/blog/dispatch_once-upon-a-time/
Благодарим за помощь!
Спасибо! Я думаю, вы, конечно, что-то о архитектуре. Вся эта загрузка с диска добавляется после того, как приложение было заархивировано и, очевидно, оно не играет с ним хорошо. WKNetworkManager (sharedManager) вызывает '[self loadQueueFromDisk];'. Поэтому, в свою очередь, создавая декодированные объекты, эти инициализации объектов инициируют вызовы sharedManager. Это может быть проблематично. Связанное решение выглядит громоздким. Как вы думаете, будет ли выполняться блок-оператор loadQueueFromDisk для делегирования задачи другому потоку? – Marcel
Если вам понравился вопрос, повысьте его! – Raspu
Ну, основные данные и потоки, которые могут быстро усложниться. Мой первый наклон для инициализации Core Data с удалением диска, как это, заключается в том, чтобы бросить его в очередь с низким приоритетом GCD 'dispatch_async (dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_LOW, 0),^{[self loadQueueFromDisk];});' поэтому он получает очереди с высоким и нормальным приоритетом пустые. Поскольку это, скорее всего, будет желательным поведением при запуске. –