Почему я предпочитаю создавать NSManagedObjectContext для каждого нового потока или NSOperation вместо вызова Core Data в основном потоке? - PullRequest
4 голосов
/ 01 июня 2011

Некоторые разработчики уже сказали мне, что я могу создать новый экземпляр NSManagedObjectContext для каждого нового потока, чтобы сделать Core Data поточно-ориентированным.Тогда я просто должен был бы позаботиться о слиянии впоследствии.

Для меня это звучит ОЧЕНЬ МНОГО дополнительного кода и накладных расходов.

Есть ли причина, по которой это решение будет плохим?Вот оно:

Вместо того, чтобы создавать новый MOC для каждого нового потока или для каждой операции NSO, я выполнял бы изменения MOC в основном потоке, как мы знаем из UIKit.Я просто позвонил бы -performSelectorOnMainThread:...waitUntilDone:YES и избавился бы от всех проблем параллелизма Core Data.

Плюсы: - Не нужно создавать новый MOC для каждой операции Thread / NSOperation.- Не нужно объединять МОК вместе.- Конечно, нет проблем с параллелизмом, поскольку Core Data остается в главном потоке, где он безопасен.

Минусы: - Вызовы типа -performSelectorOnMainThread:...waitUntilDone:YES выглядят некрасиво, трудно читаемыми.- Тема / NSOperation заблокирована.Но на самом деле система не может делать несколько вещей одновременно.В моем случае, часть Core Data не является узким местом производительности.Это тяжелые вычисления вокруг него, которые идут в фоновом потоке или NSOperation.

Что вы думаете?Стоит ли исследовать это дальше?Почему вы все еще предпочитаете создавать MOC для каждого нового потока / NSOperation, а затем заниматься слиянием?В чем преимущество этого по сравнению с основным потоком?

Ответы [ 2 ]

5 голосов
/ 01 июня 2011

Основная причина выполнения интенсивных операций в фоновом потоке / операции заключается в том, что пользовательский интерфейс работает в переднем / основном потоке.Если в основном потоке выполняется интенсивная операция с базовыми данными, пользовательский интерфейс будет не отвечать и, возможно, заставит пользователя думать, что приложение зависло или зависло.Поскольку большинство приложений повсюду демонстрируют, по крайней мере, некоторое движение при интенсивной работе, пользователь был обучен ожидать, что не отвечающий или статический пользовательский интерфейс указывает на сбой или зависание.

Мобильные пользователи также намного более чувствительны к времени ожидания.Если вы сидите за своим столом и потягиваете чашку кофе, 45-секундная пауза кажется недолгой.Если вы идете через аэропорт, это так.

Удаление интенсивных операций из основного потока позволяет пользовательскому интерфейсу продолжать функционировать.В некоторых случаях это означает, что пользователь может продолжать работать, в других это означает, что вы можете динамически обновлять пользовательский интерфейс, чтобы сообщить, что приложение работает над интенсивной операцией, и поэтому пользователь должен ждать.

Это существенно влияет на то, как пользователи воспринимают качество и удобство использования вашего приложения.

Сказав это, я не буду беспокоиться об использовании фонового потока / операций, пока вы не протестируете приложение и не обнаружите, что Core Data не может обрабатывать обработку в основном потоке.В подавляющем большинстве случаев это возможно.Медленные загрузки с серверов, вероятно, являются основной причиной необходимости фоновых операций.Если у вас их нет, скорее всего, у вашего приложения не будет серьезного фона.

1 голос
/ 01 июня 2011

«Доступ к диску дорогой» - нам сказали ...

Если вы извлекаете или сохраняете большое количество данных, дает преимущество использования отдельного MOC в операции NSThread / NSOperation. В сочетании с переходом представления это может значительно улучшить восприятие «скорости» в вашем приложении, поскольку основной поток остается выполнять только переходные элементы пользовательского интерфейса.

Я думаю, что вы могли бы найти свой ответ, измерив сколько времени вы фактически тратите на доступ к вашему магазину по сравнению с отзывчивостью вашего пользовательского интерфейса (IIRC: попробуйте CoreData и CoreAnimation Instruments), и сравните оба сценария: используя разные MOC на поток против вызова -performSelectorOnMainThread:...waitUntilDone:YES

Кстати, если вы сохраняете в фоновом потоке, вам также необходимо учитывать, что происходит, когда ваше приложение завершается во время выполнения операции сохранения. Фоновые потоки убиваются сразу же, в то время как сторожевой таймер ждет 5 секунд, пока основной поток завершит работу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...