Сохранить объекты основных данных в памяти от несвязанного кода? - PullRequest
0 голосов
/ 12 мая 2018

Я работаю над старым невероятно плохо написанным приложением Objective-C.Функция, над которой я работаю, включает в себя получение разных типов записей из основных данных и отправку их на сервер.И один тип записи (A) должен быть отправлен перед отправкой другого (B).

РЕДАКТИРОВАТЬ: A относится к ActivitySession объектам и B относится к ActivityRun объектам.

Вот проблема: где-то в приложении есть какой-то слушатель, удаляющий все записи B после отправки записей A.Я провел некоторое время, пытаясь выяснить, где это происходит, но мне не повезло.Моим решением было просто загрузить все записи B в память перед отправкой записей A (думая, что даже если записи B будут удалены из основных данных, они все равно будут существовать в памяти).Но я обнаружил, что после того, как B-записи удалены из основных данных, мой массив записей также очищается.

Вот сущность логики, о которой я говорю:

__block NSArray* activityRuns = [coreData fetchByEntitiyName:@"ActivityRun"];

NSLog(@"---> Sending %@ students", @([students count]));
return [self sendStudents:students withApiKey:apiKey]
.then(^{
  // This must happen before sending anything with activity references
  NSLog(@"---> Fetching activities");
  return [self fetchActivitiesWithApiKey:apiKey];
})
.then(^{
  NSArray* data = [coreData fetchByEntitiyName:@"ActivitySession"];
  NSLog(@"---> Sending %@ activity sessions", @([data count]));
  return [self sendActivitySessions:data withApiKey:apiKey].catch(failLogger(@"Failed to upload activity sessions", nil));
})
.then(^{
  NSLog(@"---> Sending %@ activity runs", @([activityRuns count]));
  return [self sendActivityRuns:activityRuns withApiKey:apiKey].catch(failLogger(@"Failed to upload activity runs", nil));
})

activityRuns - это данные в памяти, которые я пытаюсь отправить (с [self sendActivityRuns:activityRuns withApiKey:apiKey]).Вот как определяется fetchByEntitiyName:

- (NSArray*) fetchByEntitiyName:(NSString*) entityName {
    NSFetchRequest* fetchRequest = [[NSFetchRequest alloc] initWithEntityName:entityName];
    NSError* error = nil;
    NSArray* results = [_mainQueueContext executeFetchRequest:fetchRequest error:&error];
    if (results == nil) {
            ELog(@"--- Failed to fetch %@: %@", entityName, error);
            return @[];
    }
    return results;
}

activityRuns не используется / не передается нигде, кроме приведенного выше фрагмента кода, где каждый запуск операции отправляется с использованием HTTP-запроса.Я попытался добавить точки останова сразу после создания массива (объекты действительны и содержат данные) и непосредственно перед отправкой (все они nil).

Как сохранить основные данные отгадить на мои объекты в памяти, когда что-то удаляет записи?

Ответы [ 2 ]

0 голосов
/ 12 мая 2018

Простое решение:

Почему бы вам не подготовить все данные, которые нужно отправить на сервер сначала , включая формат и сериализацию? Затем вы можете сохранить это в памяти или в другом месте и отправить на ваш сервер в правильном порядке.

0 голосов
/ 12 мая 2018

Есть несколько способов, чтобы это произошло:

  • Очевидным является вызов NSManagedObjectContext.deleteObject, просто найдите deleteObject и установите точки останова.
  • Другойодин из них, если A и B имеют отношение с каскадным удалением, и вы удаляете родителя, то B удаляется.Например, если у Student есть список ActivityRun-ов в свойстве, например: student.activityRuns (массив дочерних объектов), или обратное свойство - activityRun.student (объект с одним родителем), и в вашей модели CoreData это свойство устанавливаетсякак каскадное удаление, тогда, если вы удалите студента, все ActivityRuns исчезнут.Если вы используете «on delete set null» вместо «on delete cascade», дочерние элементы не будут удалены автоматически, но вам придется удалять их вручную, когда это необходимо.Другой способ - «отсоединить» дочерний элемент от родителя, установив activityRun.student = nil;, это должно иметь тот же эффект (снова придется удалять вручную при необходимости).
  • Другой вариант - если вы выполняете необработанные запросы SQL DELETEдля этой базы данных

Существует способ просмотреть все команды CoreData SQL, которые происходят под капотом - см. здесь .

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