У меня есть действительно раздражающая проблема, которую я просто не могу понять.
У меня есть представление, когда я отправляю сообщение, которое сохраняется в Core Data, когда это было сделано, он запросил базу данных для случайного сообщения (предложения) и сохранил ее также в другой строке в базе данных.
Если я делаю последнюю часть жестко запрограммированной, не получая данные из БД, она работает отлично и денди, но как только я получаю случайную строку из БД, она сходит с ума.
В моем AppDelegate.m:
- (void)save {
NSAssert(self.context != nil, @"Not initialized");
NSError *error = nil;
BOOL failed = [self.context hasChanges] && ![self.context save:&error];
NSAssert1(!failed,@"Save failed %@",[error userInfo]);
}
- (NSString*)selectRandomSentence
{
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Sentences" inManagedObjectContext:self.managedObjectContext];
[request setEntity:entity];
NSError *error = nil;
NSUInteger count = [self.context countForFetchRequest:request error:&error];
NSUInteger offset = count - (arc4random() % count);
[request setFetchOffset:offset];
[request setFetchLimit:1];
NSArray *sentenceArray = [self.context executeFetchRequest:request error:&error];
[request release];
return [[sentenceArray objectAtIndex:0] sentence];
}
- (NSManagedObjectContext *)context {
if (_managedObjectContext != nil)
return _managedObjectContext;
NSPersistentStoreCoordinator *coordinator = [self coordinator];
if (coordinator != nil) {
_managedObjectContext = [[NSManagedObjectContext alloc] init];
[_managedObjectContext setPersistentStoreCoordinator:coordinator];
}
return _managedObjectContext;
}
В моем ChatController.m:
- (void)didRecieveMessage:(NSString *)message
{
[self addMessage:message fromMe:NO];
}
#pragma mark -
#pragma mark SendControllerDelegate
- (void)didSendMessage:(NSString*)text {
[self addMessage:text fromMe:YES];
}
#pragma mark -
#pragma mark Private methods
- (void)responseReceived:(NSString*)response {
[self addMessage:response fromMe:NO];
}
- (void)addMessage:(NSString*)text fromMe:(BOOL)fromMe {
NSAssert(self.repository != nil, @"Not initialized");
Message *msg = [self.repository messageForBuddy:self.buddy];
msg.text = text;
msg.fromMe = fromMe;
if (fromMe)
{
[self.bot talkWithBot:text];
}
[self.repository asyncSave];
[self.tableView reloadData];
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:[self.buddy.messages count] - 1] atScrollPosition:UITableViewScrollPositionBottom animated:YES];
}
В My OnlineBot.m:
- (void)talkWithBot:(NSString *)textFromMe
{
AppDelegate *delegate = [[UIApplication sharedApplication] delegate];
[self didRecieveMessage:[delegate selectRandomSentence]];
}
- (void)didRecieveMessage:(NSString *)message
{
if ([self.delegate respondsToSelector:@selector(didRecieveMessage:)])
[self.delegate didRecieveMessage:message];
}
Repository.m
- (Message*)messageForBuddy:(Buddy*)buddy {
Message *msg = [self.delegate entityForName:@"Message"];
msg.source = buddy;
[self.delegate.managedObjectContext refreshObject:buddy mergeChanges:YES];
return msg;
}
- (void)asyncSave {
[self.delegate save];
}
Ошибка:
2012-08-10 00: 28: 20.526 Чат [13170: c07] * Ошибка утверждения в - [AppDelegate save],/Users/paulp/Desktop/TestTask/Classes/AppDelegate.m:28 2012-08-10 00: 28: 20.527 Чат [13170: c07] * Завершение приложения из-за неотображения исключение "NSInternalInconsistencyException", причина: "Сохранить не удалось" {type = immutable dict, count = 2, entries = > 1: {contents = "NSAffectedObjectsErrorKey" } = ( "(entity: Sentences; id: 0x6b8bf10; data:)" ) 2: {contents = "NSUnderatingException" } = CoreData не может выполнить ошибку для "0x6b8bf10 '}
Что я делаю неправильно?
Обновление Я указал ошибку на эту строку:
NSArray *sentenceArray = [self.context executeFetchRequest:request error:&error];
Когда я выполняю эту строку, я получаю ошибку... то есть при извлечении данных. Ошибка, однако, кажется, появляется при сохранении новых данных в сущности Messages. Случайное предложение выбирается из предложений.
После того, как я изменил метод asyncSave на сохранение напрямую (таким образом, не используя новый поток), он сохраняет первый чат, но после этого ничего не происходит. Он умирает.
Обновление
Кажется, все это работает с помощью этого в didFinishLaunchingWithOptions
:
[self.context setRetainsRegisteredObjects:YES];
Я понимаю, что здесь Контекст объектной модели CodeData не выпускает свои объекты, что, по-видимому, является проблемой между добавлением и сохранением betweens. Но почему?