Основные атрибуты сохранения данных объектов

#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; Еще раз спасибо! Этот сайт создан такими людьми, как вы, которые создают отличные решения за короткий промежуток времени! 🙂