#cocoa-touch #core-data #fetch
#cocoa-touch #основные данные #выборка
Вопрос:
Этот вопрос касается основных данных.
Я создал объект под названием TV с тремя атрибутами: name, price и size. Я также создал подкласс NSMutableObject с файлами TV.h и TV.m.
Я импортировал TV.h в свой DetailViewController.h, который обрабатывает мои ползунки и пользовательские элементы, значения которых я хочу принять.
Итак, я выполнил запрос на выборку, и все работает нормально, НО:
Каждый раз, когда я обновляю пользовательский интерфейс (valueDidChange:), Xcode создает КОПИЮ моей сущности и добавляет ее в мой ТВ-объект.
Все, что я хочу, чтобы Xcode просто редактировал и сохранял в текущем объекте, а не редактировал и сохранял в новом объекте.
Помощь очень ценится!
Заранее благодарю вас.
Мой код:
DetailViewController.m
- (IBAction)collectSliderValue:(UISlider *)sender {
if (__managedObjectContext == nil) {
NSLog(@"Problem ...");
__managedObjectContext = [(MasterViewController *)[[UIApplication sharedApplication] delegate] managedObjectContext];
NSLog(@"... solved!");
}
if (sender == sizeSlider) {
NSError *error = nil;
NSManagedObjectContext *context = [self managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"TV" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:amp;error];
TV * currentTV = [[TV alloc] initWithEntity:entity insertIntoManagedObjectContext:context];
currentTV.size = [[NSNumber alloc] initWithInt:(sender.value 0.5f)];
currentTV.name = @"New TV!";
NSError *error11;
[__managedObjectContext save:amp;error11];
for (NSManagedObject *info in fetchedObjects)
{
NSLog(@"Name = %@", [info valueForKey:@"name"]);
NSLog(@"Size = %@", [info valueForKey:@"size"]);
NSLog(@"Price = %@", [info valueForKey:@"price"]);
}
[fetchRequest release];
}
Ответ №1:
//Editing begins ...
TV * currentTV = [[TV alloc] initWithEntity:entity insertIntoManagedObjectContext:context];
Редактирование не начинается, вы создаете новый объект прямо там. Вашему контроллеру представления требуется переменная экземпляра для хранения текущего TV
объекта, который вы изменяете.
В созданном вами проекте шаблона переменная detailItem
содержит управляемый объект, который вы в данный момент редактируете. Вы должны специально установить это как TV
объект и ссылаться на это вместо currentTV
в вашем коде DetailViewController. Вы должны удалить весь запрос на выборку и контекстный код управляемого объекта — это не относится к вашему контроллеру подробного представления, им должен управлять главный контроллер представления.
Итак, в DetailViewController.h:
@property (strong, nonatomic) id detailItem;
становится
@property (strong, nonatomic) TV detailItem;
И в вашем методе collectSliderValue это должно выглядеть намного проще, например, так:
- (IBAction)collectSliderValue:(UISlider *)sender
{
if (sender == sizeSlider)
self.detailItem.size = [NSNumber numberWithFloat:sender.value];
}
Сохранение контекста управляемого объекта не должно происходить до тех пор, пока оно не вернется в ваш контроллер представления сведений, об этом позаботится делегат вашего приложения.
В ваш файл master detail controller .m также может потребоваться импортировать файл TV.h, чтобы он знал, что TV является NSManagedObject
подклассом. Кроме того, при настройке элемента сведений выполняется передача на телевизор:
self.detailViewController.detailItem = (TV*)selectedObject;
Комментарии:
1. Пока спасибо. Какой код для «сохранения текущего объекта TV, который я изменяю»? Или: как я могу инициализировать свою
TV
сущность без создания новой?2. Пока спасибо. Я отредактировал свой пост. Да, это единственное место. Цель состоит в том, чтобы сохранить значение ползунка путем изменения и установить ползунок на это значение после перезапуска программы. Может быть, это помогает: я работал с шаблоном Apple Core Data (iPad) с UISplitView.
3. Это сложно описать, в том числе потому, что я не являюсь носителем языка… Я бы рекомендовал открыть новый проект Xcode, выбрать iPad и шаблон SplitView с флажками «Использовать раскадровку» и «Использовать CoreData». Тогда вы находитесь в моей настройке. В основном шаблон добавляет новый объект нажатием кнопки. (UIBarButtonItem) и отображает его в виде таблицы. Я просто хочу обновить этот объект с помощью моего слайдера. Я уже изменил тип атрибута с
NSDate
наNSNumber
и добавил два других атрибута, как я сказал. Все работает нормально, но есть проблема с сохранением… Пока спасибо!4. Я попробую — может быть, не в течение нескольких часов, хотя 🙂 Никогда бы не подумал, что вы не являетесь носителем языка, ваш английский превосходен.
5. Привет, младший! Спасибо за ваш комплимент и указание
id detailItem
. Кажется, это работает довольно хорошо (по крайней мере, с несколькими оптимизациями наверняка 😉 ). Теперь я проверю, действительно ли объект сохранен глобально или это просто локальное изменение. Я получаю последнее сообщение об ошибкеmasterViewController.m
:Semantic Issue - Incompatible pointer types assigning to 'TV *' from 'NSManagedObject *'
в этой строкеself.detailViewController.detailItem = selectedObject;
Еще раз спасибо! Этот сайт создан такими людьми, как вы, которые создают отличные решения за короткий промежуток времени! 🙂