Удаление объектов Core Data

Я добавляю основные данные в свое приложение для iPad. Моя общая процедура состоит в том, чтобы протестировать код, поместив его в делегат приложения. Когда я удовлетворен тем, что код проанализирован правильно, я перемещаю его в соответствующий метод в другом месте приложения. До сих пор это работало с добавлением объектов. Но у меня проблемы с удалением объектов. Я могу удалить их из делегата приложения, выбрав и удалив их, и прямо сейчас я удаляю их все при запуске приложения, просто чтобы поддерживать чистоту базы данных, пока у меня не будет работать основной код данных.

Итак, хватит моего рабочего процесса. Проблема, с которой я сталкиваюсь сейчас, заключается в удалении объекта из соответствующего места. Давайте посмотрим, смогу ли я кратко описать свою установку.

У меня есть два класса, назовем их Car и Tire ради этого обсуждения. Я не знаю, что такое соглашение, поэтому я придумал свое, а именно добавить C_ в начало имени связанных объектов Core Data для хранения объектов, связанных с этими объектами. Итак, у меня есть два дополнительных класса, C_Car и C_Tire. У каждой машины может быть несколько шин, поэтому Car имеет свойство tires, которое является NSSet из Tire *. Кроме того, Car имеет свойство CarCD типа C_Car *, а Tire имеет свойство TireCD типа C_Tire *, так что каждый объект может отслеживать связанный с ним объект основных данных (CD предназначен для основных данных).

Xcode создает удобные методы для добавления или удаления объектов. Среди них метод добавления шины к автомобилю. Я использую это таким образом:

tire.tireCD = tireCD; //tire is an object of type Tire *, and tireCD is an object of type C_Tire *.
[self.carCD addTireObject:tireCD];//self.carCD is a property in my view controller of type CarCD *, and tireCD is a local object of type TireCD *.

Кроме того, есть удобный способ снять шину с автомобиля - (void)removeTireObject:(C_Tire *)value;. Я понял, что везде в моем контроллере представления, где у меня было:

[tireObject removeFromSuperview];//tireObject is a (Tire *) object.

Я бы просто изменил это на:

[carObject removeTireObject:tireObject.tireCD];
[tireObject removeFromSuperview];

Первая строка должна удалить объект из NSSet основного объекта данных. Вторая строка удаляет объект из объекта автомобиля, используемого в приложении.

Проблема в том, что я не вижу никакого SQL, генерируемого в окне отладчика, когда этот код выполняется. Я что-то упускаю?

Кроме того, если вы хотите прокомментировать соглашения об именах, сейчас самое время для меня принять то, что является общепринятым.


person Victor Engel    schedule 29.06.2013    source источник
comment
Используя po для запроса объекта CarCD, я вижу, что удаление действительно происходит. Я думаю, что моя ошибка в том, что я не удалял объект TireCD, а только удалял его ссылку из объекта CarCD.   -  person Victor Engel    schedule 29.06.2013
comment
Я не понимаю, почему у вас 2 набора классов (Car/Tire и C_Car/C_Tire). Должно быть достаточно одного подкласса управляемых объектов для каждого объекта.   -  person Martin R    schedule 29.06.2013
comment
Не все свойства Car and Tire необходимо сохранять в основных данных. C_Care и C_Tire содержат только те свойства, которые необходимо сохранить. Другие свойства Car и Tire необходимы в приложении, но не основные данные. Я надеюсь, что в этом есть смысл.   -  person Victor Engel    schedule 29.06.2013
comment
P.S. Одним из них является NSMagagedObject. Другой нет.   -  person Victor Engel    schedule 29.06.2013
comment
А автомобиль/шина - это UIView? Шина является подвидом автомобиля?   -  person Martin R    schedule 29.06.2013
comment
Обратите внимание, что операторы SQLite будут отображаться только тогда, когда контекст управляемого объекта сохранен.   -  person Martin R    schedule 29.06.2013
comment
@MartinR, я это понимаю. Моя проблема заключалась в том, что я удалял ссылку из NSSet, но не удалял объект. Я добавил вызов [context deleteObject:], и он сработал, как и ожидалось. Просто глупая оплошность.   -  person Victor Engel    schedule 29.06.2013
comment
Да, Car и Tire являются подклассами UIView, а Tire — подклассом Car.   -  person Victor Engel    schedule 29.06.2013
comment
Итак, ваша проблема решена или остались вопросы? - (Кстати, обратите внимание, что deleteObject:tire автоматически удалит шину из объекта автомобиля, если для правила удаления основных данных установлено значение Nullify.)   -  person Martin R    schedule 29.06.2013
comment
Я удаляю объект C_Tire. Базовые данные автоматически удаляют ссылку на них в C_Car, поэтому я могу опустить вызов вспомогательного метода [carObject removeTireObject:tireObject.tireCD];.   -  person Victor Engel    schedule 29.06.2013
comment
Да, если правило удаления для связи между C_Tire и C_Car установлено на Nullify.   -  person Martin R    schedule 29.06.2013
comment
да. Проблема решена. Единственная оставшаяся проблема — это соглашения об именах для основных объектов данных. Есть ли конвенция?   -  person Victor Engel    schedule 29.06.2013


Ответы (1)


(Это краткое изложение приведенных выше комментариев плюс некоторые дополнительные замечания.)

  • [car removeTireObject:tire] просто удаляет шину с автомобиля, но не удаляет объект шины. Чтобы удалить объект, вызовите [context deleteObject:tire].
  • Удаление шины автоматически удалит ее из связанного автомобиля, если «Правило удаления» для связи между C_Tire и C_Car установлено на «Обнулить».
  • Изменения Core Data записываются на диск только в том случае, если контекст сохранен, и только тогда вы увидите выходные данные отладки SQLite.

Соглашения об именах см. в разделе "Соглашения" в разделе «Программирование с помощью Objective-C». Некоторые замечания:

  • Использование подчеркивания в именах классов (как мне кажется) необычно. Лучшими именами классов для классов управляемых объектов могут быть CDCar, CDTire или, если вы следуете предложению использовать трехбуквенный префикс, XYZCar, XYZTire, где XYZ — это выбранный вами префикс.
  • Я бы использовал CarView, TireView для UIView подклассов.
person Martin R    schedule 29.06.2013