Я работаю над этой проблемой сейчас в течение многих дней, и мне нужна помощь, потому что я не уверен как действовать. Проблема, с которой я столкнулся (что станет понятнее, когда вы прочитаете этот вопрос), я не уверен, как получить существующий NSManagedObject, если он уже существует при создании нового.Создание нового базового объекта данных, если оно не существует, или получение существующего объекта, если оно существует с основными данными
Давайте сделаем шаг назад, чтобы посмотреть на Модель, и предпосылка приложения проста; позволяют пользователям создавать «Транзакции», которые имеют имя, сумму, случай и дату - при создании новой транзакции пользователю должно быть разрешено выбирать существующее имя. Модель данных:
- Сделка Entity с wasGiven атрибут
- Person Entity с атрибутом имени
- Случай Entity с названием атрибута
- Item Entity с количеством атрибутов
сделка имеет отношения к объекту Person (whoBy), ссылку на сущность события (случай) и ссылку на Entity Item (itemType).
Приложение представляет собой простой 2 Tableb-ed Table View Controller - первая вкладка содержит всю информацию, разделенную датами. Вторая вкладка содержит только информацию «Имя». Существует кнопка «плюс», и когда пользователь нажимает на нее, ей предоставляется модальный вид, чтобы добавить имя, случай, количество и дату. Они нажимают кнопку сохранения и сохраняют ее в базе данных основных данных.
Задача Создание новой транзакции с новым именем создает это идеально. Создание новой транзакции с существующим именем (при вводе пользователем с идентичным именем пользователя) создает новый объект на первой вкладке в виде отдельной записи (правильно), но на вкладке имени создается дублирующее имя для этого человека. Когда вы нажимаете на одно из повторяющихся имен, он показывает обе транзакции. Проблема здесь в том, что похоже, что он создает новый объект Person каждый раз вместо ссылки.
Код
Я прошел через несколько итераций, чтобы попытаться получить эту работу, и вот последний код, используя подклассы NSManagedObject.
Управляемый объектObjectContext получен из приложения-делегата.
Название, событие, количество и дата хранятся в их собственных текстовых полях.
AddEntry.m - Сохранить метод
- (IBAction)save:(id)sender
{
NSManagedObjectContext *context = [self managedObjectContext];
Transaction *transaction = [NSEntityDescription insertNewObjectForEntityForName:@"Transaction" inManagedObjectContext:context];
Item *itemType = [NSEntityDescription insertNewObjectForEntityForName:@"Item" inManagedObjectContext:context];
Person *p = (Person *)[Person personWithName:self.nameTextField.text inManagedObjectContext:context];
Occasion *o = (Occasion *)[Occasion occasionWithTitle:self.occasionTextField.text andEventDate:self.dateTextField.text inManagedObjectContext:context];
transaction.whoBy = p;
occasion.title = self.occasionTextField.text;
transaction.occasion = o;
itemType.amount = self.itemTextField.text;
transaction.item = itemType;
transaction.wasReceived = @(self.isReceivedSegment.selectedSegmentIndex == 0);
NSError *error = nil;
if (![context save:&error])
{
NSLog(@"Can't save! %@ %@", error, [error localizedDescription]);
}
[self dismissViewControllerAnimated:YES completion:nil];
}
Это, конечно, вызывает подкласс Person NSManagedObject и здесь, где я прошел через несколько итераций.
Person NSManagedObject Подкласс - Итерация 1 - Предикаты
+ (Occasion *)eventWithName:(NSString *)title andEventDate:(NSString *)date inManagedObjectContext:(NSManagedObjectContext *)context;
{
Occasion *occasion = nil;
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Occasion"];
request.predicate = [NSPredicate predicateWithFormat:@"title = %@", title];
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"title" ascending:YES];
request.sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
NSError *error = nil;
NSArray *occasions = [context executeFetchRequest:request error:&error];
if (!occasions)
{
// Handle Error
}
else if (![occasions count])
{
occasion = [NSEntityDescription insertNewObjectForEntityForName:@"Occasion" inManagedObjectContext:context];
occasion.title = title;
}
else
{
occasion = [occasions lastObject];
}
occasion.dateOfEvent = date;
return occasion;
}
Проблема Это несколько работ.Я поставил точку останова, и возвращаемый «человек», который возвращается сюда, и метод сохранения в Add Entry тот же, если объект уже существует и новый, если это новый объект, но когда дело доходит до второй вкладки, добавив вторую запись для того же человека.
Итерация 2 - ObjectId
С пытается получить идентификатор объекта, я получаю тот же результат дублированных записей во второй вкладке:
+ (Person *)personWithName:(NSString *)name inManagedObjectContext:(NSManagedObjectContext *)context;
{
Person *person;
NSManagedObjectID *personID = person.objectID;
if (!personID)
{
person = [NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:context];
person.name = name;
return person;
}
else
{
return person;
}
}
В случае имеет значение, то Вторая вкладка в fetchRequest выглядит следующим образом:
- (NSFetchedResultsController *)fetchedResultsController
{
if (_fetchedResultsController != nil)
{
return _fetchedResultsController;
}
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Occasion" inManagedObjectContext:managedObjectContext];
fetchRequest.entity = entity;
NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"title" ascending:NO];
fetchRequest.sortDescriptors = [NSArray arrayWithObject:sort];
fetchRequest.fetchBatchSize = 20;
NSFetchedResultsController *theFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:nil cacheName:nil];
self.fetchedResultsController = theFetchedResultsController;
_fetchedResultsController.delegate = self;
return _fetchedResultsController;
}
EDIT Мне интересно, есть ли тот факт, что у меня нет предиката здесь, во второй вкладке fetchRequest означает, что он иллюстрирует ВСЕ объекты.
Конечно, я буду в будущем проверять это, потому что на первой вкладке, когда я нажмите на ячейку, я бы хотел, чтобы эта транзакция прошла, чтобы я мог редактировать поле.
Это сводит меня с ума и действительно останавливает мое приложение от прогрессирования, поэтому любая помощь здесь была бы оценена по достоинству!
EDIT: Модель данных в комплекте
Вы отлаживали «он все еще добавляет вторую запись для одного и того же человека» - это одно и то же MO в листинге дважды? Или у вас 2 с тем же именем? – Wain
Привет @ Хороший вопрос - я должен проверить, что - тот же самый возвращаемый человек присутствовал при использовании существующего имени, но это не значит, что МО было одинаковым - какой был бы лучший способ отладить это? – amitsbajaj
Если я правильно понимаю, что «whoBy» - это отношение. Как это определяется? – AntonijoDev