2010-07-21 2 views
1

У меня есть приложение UIKit с базовыми данными, которое позволяет пользователю перемещать объекты на экране. Пока объект перетаскивается, я обновляю его атрибут позиции на каждом событии touchesMoved:. Чтобы поддержать отмену операции перетаскивания за один раз, я начинаю новую группу отмены в начале перетаскивания и завершаю группу, когда пользователь поднимает их палец.Сочетание данных ядра для действия, охватывающего несколько циклов цикла цикла

Чтобы экономить память и быстро выполнять операции отмены, я хочу объединить данные отмены, относящиеся к операции перетаскивания, но Core Data затрудняет это. Проблема в том, что processPendingChanges вызывается в конце каждого цикла цикла цикла, и он заставляет Core Data записывать новую отменную запись для изменения позиции, которое произошло в этой итерации. Операция перетаскивания может легко накапливать сотни таких записей отмены, все из которых, но первые, не нужны.

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

ответ

3

Я думаю, что установка менеджеров отмены setGroupsByEvent: будет делать то, что вы хотите.

задает логическое значение, указывающее, автоматически ли приемник группы отмены операции во время выполнения цикла . Если ДА, приемник создает группы отмены по каждому проходу через цикл запуска; если НЕТ нет.

Более чистым решением может быть просто не зафиксировать положение объектов в модели данных до конца события перетаскивания.

+0

К сожалению, 'setGroupsByEvent:' здесь не помогает. Перетаскивание охватывает несколько событий, поэтому, если я неправильно понял что-то базовое, нет никакой возможности явно группировать мои изменения с помощью 'beginUndoGrouping' /' endUndoGrouping', а 'setGroupsByEvent' становится no-op, пока есть открытая группа. Не изменять модель до конца жеста перетаскивания, вероятно, лучший способ пойти. Проблема в том, что мне некуда хранить временную позицию - я делаю рендеринг непосредственно из модели без каких-либо отдельных объектов вида. Но, возможно, это означает, что пришло время добавить их сейчас! –

+0

IIRC, устанавливая 'groupsByEvent' на' NO', вы получаете одну длинную группу отмены, которая превосходит цикл выполнения. – TechZen

+0

* Sigh * Нет, установка 'groupsByEvent' на' NO' просто отключает неявную группировку, поэтому вам всегда нужно начинать и заканчивать свои собственные группы. Да, группы, которые вы сами создаете, очевидно, могут выйти за одну итерацию цикла запуска. Это был не вопрос. Вопрос заключался в использовании памяти и производительности, возникающей в результате автоматического вызова 'performPendingChanges' в конце каждой итерации цикла выполнения. Решение, которое вы предложили, является хорошим способом: если модель изменяется только в конце жеста, 'performPendingChanges' не будет регистрировать новое действие отмены в каждой итерации цикла цикла. –

0

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

Если у вас есть groupsByEvent, вам нужно иметь в виду, что менеджер отмены игнорирует все групповые сообщения, когда регистрация отключена, включая ту, которая автоматически закрывает неявную группу в конце события. Так что если вы планируете оставить регистрации выключенными в конце цикла выполнения, вам придется вручную закрыть неявную группе себя:

[moc processPendingChanges]; 
while ([moc.undoManager groupingLevel]) 
    [moc.undoManager endUndoGrouping]; 
[moc.undoManager disableUndoRegistration]; 

После того, как жест перетаскивания закончен, вы можете повторно включить регистрацию отменить с кодом:

[moc processPendingChanges]; 
[moc.undoManager enableUndoRegistration]; 

Это решение работает, но оно немного клочковое. Тот, который предлагается TechZen, намного чище: не обновляйте атрибуты модели до тех пор, пока не будет достигнут жест перетаскивания.

+0

Оказывается, подход более чистого подхода не соответствовал моему приложению - систематическое введение отдельного (независимо настраиваемого) дерева представлений параллельно моим объектам модели привело бы к слишком большому числу осложнений. Я закончил тем, что использовал это более простое решение. –

Смежные вопросы