Iphone Core Data сбой при сохранении

В настоящее время я пишу приложение Iphone с использованием Core Data и получаю ошибку EXC_BAD_ACCESS во время строки кода [managedObjectContext save: & ошибка]. Этот сбой происходит только после изменения некоторых полей. Более конкретно, мой объект имеет два строковых поля (из примерно 10 полей), которые получают свои значения из возврата модального контроллера представления (например, текстового редактора). Сбой также происходит только после того, как эти поля будут отредактированы, первый раз, когда я положил значение, он отлично работает.

Причина, по которой у меня есть строка с конструкторами форматирования с единственными строками, заключается в том, что я пытался копировать конструкцию... не уверен, что это происходит автоматически? Мысль, возможно, сохранить/освободить сообщения от этих строк (эти два из модального контроллера), были освобождены при увольнении модального контроллера или что-то в этом роде. Угадайте, хотя, потому что он все еще не работает.

Здесь раздел кода, который сбой:

[Изменено]

        - (void)actionSheet:(UIActionSheet *)modalView clickedButtonAtIndex:    (NSInteger)buttonIndex
      switch(buttonIndex) {
              case 0: {
                if(message == nil) {
                  message = [NSEntityDescription insertNewObjectForEntityForName:@"MailMessage" inManagedObjectContext:self.managedObjectContext];
                }
                message.toString = txtTo.text;
                message.fromString = txtFrom.text;
                message.subjectString = txtSubject.text;
                message.backgroundColor = [NSNumber numberWithInt:[bgColor intValue]];
                message.textArray = [NSString stringWithFormat:@"%@", stringTextArray];
                message.htmlString = [NSString stringWithFormat:@"%@", stringHTML];
                message.timeStamp = [NSDate date];
                message.statusCode = [NSNumber numberWithInt:0];
                NSError *error = nil;
                if (![message.managedObjectContext save:&error]) {
                    abort();
                }   
                break;
               }
              case 1: {
             break;
              }
      }
      if(buttonIndex != modalView.cancelButtonIndex) {
      [webViewBody loadHTMLString:@"<html><head></head><body></body></html>" baseURL:[NSURL URLWithString:@""]];
      [self.navigationController popToRootViewControllerAnimated:YES];
}

}

И вот журнал сбоев:

Exception Type:  EXC_BAD_ACCESS (SIGBUS)
Exception Codes: KERN_PROTECTION_FAILURE at 0x00000015
Crashed Thread:  0

Thread 0 Crashed:
0   libobjc.A.dylib                 0x30011940 objc_msgSend + 20
1   CoreData                        0x367f7d3e -[NSKnownKeysDictionary1 dealloc] + 82
2   CoreData                        0x367f7cda -[NSKnownKeysDictionary1 release] + 34
3   CoreData                        0x3687eec4 -[NSManagedObject(_NSInternalMethods) _setOriginalSnapshot__:] + 40
4   CoreData                        0x36821030 -[NSManagedObjectContext(_NSInternalAdditions) _clearOriginalSnapshotAndInitializeRec:] + 16
5   CoreData                        0x368205f2 -[NSManagedObjectContext(_NSInternalAdditions) _didSaveChanges] + 958
6   CoreData                        0x368133bc -[NSManagedObjectContext save:] + 412
7   Decome                          0x0001fdd6 -[CreateMessageViewController actionSheet:clickedButtonAtIndex:] (CreateMessageViewController.m:163)
8   UIKit                           0x30a6cbd8 -[UIActionSheet(Private) _buttonClicked:] + 256
9   CoreFoundation                  0x30256dd4 -[NSObject performSelector:withObject:withObject:] + 20
10  UIKit                           0x3096e0d0 -[UIApplication sendAction:to:from:forEvent:] + 128
11  UIKit                           0x3096e038 -[UIApplication sendAction:toTarget:fromSender:forEvent:] + 32
12  UIKit                           0x3096e000 -[UIControl sendAction:to:forEvent:] + 44
13  UIKit                           0x3096dc58 -[UIControl(Internal) _sendActionsForEvents:withEvent:] + 528
14  UIKit                           0x309a6e9c -[UIControl touchesEnded:withEvent:] + 452
15  UIKit                           0x309a60d4 -[UIWindow _sendTouchesForEvent:] + 520
16  UIKit                           0x309a5464 -[UIWindow sendEvent:] + 108
17  UIKit                           0x30936e3c -[UIApplication sendEvent:] + 400

Любая помощь приветствуется, спасибо.

ОБНОВЛЕНИЕ: Кроме того, несмотря на то, что программа выходит из строя, когда я открываю ее резервную копию, данные сохраняются правильно. Таким образом, EXC_BAD_ACCESS должен произойти после того, как сохранение достигнет, по крайней мере, достаточно, чтобы хранить в постоянном хранилище, который я думаю.

Если я закомментирую строку сохранения, код теперь работает нормально. Но это не спасает после того, как я закрываю и выхожу. Если я запустил строку сохранения в моей функции Root View Controllers willAppear, она выдаст ту же ошибку EXC_BAD_ACCESS. Консоль не говорит ничего, кроме EXC_BAD_ACCESS если я сделаю обратную линию, я получаю:

#0  0x30011940 in objc_msgSend ()
#1  0x367f7d44 in -[NSKnownKeysDictionary1 dealloc] ()
#2  0x367f7ce0 in -[NSKnownKeysDictionary1 release] ()
#3  0x3687eeca in -[NSManagedObject(_NSInternalMethods) _setOriginalSnapshot__:] ()
#4  0x36821036 in -[NSManagedObjectContext(_NSInternalAdditions) _clearOriginalSnapshotAndInitializeRec:] ()
#5  0x368205f8 in -[NSManagedObjectContext(_NSInternalAdditions) _didSaveChanges] ()
#6  0x368133c2 in -[NSManagedObjectContext save:] ()
#7  0x0000314e in -[RootViewController viewWillAppear:] (self=0x11b560, _cmd=0x3014ecac, animated=1 '\001') at /Users/inckbmj/Desktop/iphone/Decome/Classes/RootViewController.m:85

Извините, что ранее код не был отформатирован должным образом. Когда этот контроллер представления создается, если он не является новым "сообщением", ему передается объект сообщения, полученный из fetchedResultsController, например:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    MailMessage *aMessage = (MailMessage *)[fetchedResultsController objectAtIndexPath:indexPath];
    [messageView loadMessage:aMessage viewOnly:NO usingTemplate:NO];
    messageView.managedObjectContext = self.managedObjectContext;
    [self.navigationController pushViewController:messageView animated:YES]; 
}

(первый набор кода из файла MessageViewController.m, который является классом, который имеет messsageView)

Он только сбой, если я представляю свой редактор EditorViewController как модальный вид, а затем возвращаюсь. Даже если я изменяю строки textArray и htmlString (на которые влияют только модальные представления):

message.textArray = @"HELLO";
message.htmlString = @"HELLO";

он по-прежнему падает. Если я прокомментирую обе строки, это не сработает.

Итак, кажется, что он сбой, если я представляю модальное представление, а затем попытаюсь отредактировать поля textArray или htmlString моего NSOManagedObject...

Вот где я представляю представление:

- (void) touchesEnded: (NSSet *) touches withEvent: (UIEvent *) event {
    if(!viewOnly) {
        UITouch *touch = [touches anyObject];
        CGPoint location = [touch locationInView: txtTo];
    location = [touch locationInView: webViewBody];
        if(CGRectContainsPoint(webViewBody.bounds, location)) {
            [editor loadTextArrayString:stringTextArray];
            [self presentModalViewController:editor animated:YES];
        }
    }
}

и где я его отклоняю:

-(void)returnWithTextArray:(NSString *)arrayString HTML:(NSString *)html bgColor:(NSNumber *)numColor {
    [self dismissModalViewControllerAnimated:YES];
    self.stringTextArray = [NSString stringWithFormat:@"%@", arrayString];
    self.stringHTML = [NSString stringWithFormat:@"%@", html];
    self.bgColor = [NSNumber numberWithInt:[numColor intValue]];
    [webViewBody loadHTMLString:self.stringHTML baseURL:[NSURL URLWithString:@""]];
}

Ответы

Ответ 1

Решил проблему, хотя я не уверен, что я обращаюсь к фактической первопричине. Ошибка была устранена, когда я добавил эту строку:

[managedObjectContext setRetainsRegisteredObjects:YES];

К тому, где я создаю managedObjectContext. Поэтому я предполагаю, что это связано с удержанием счета. Я предполагаю, что, возможно, экземпляры переменных будут выпущены частично или временно или что-то, когда будут представлены модальные представления? Я не знаю. В любом случае эта ошибка была устранена, программа теперь работает нормально.

Ответ 2

Гарантируется, что вы сохраните доступ к управляемому объекту из контекста, пока изменение ожидает этого объекта (вставка, обновление, удаление). Как только вы сделаете вызов для сохранения:, вы можете потерять ссылку на управляемый объект.

Пока вы перестали получать ошибку при установке setRetainsRegisteredObjects: ДА, возможно, вы ввели проблему управления памятью, поскольку вы устанавливаете время жизни управляемого объекта в зависимости от времени жизни контекста управляемого объекта. Если вы передаете свой контекст во всем своем приложении, это может стать довольно большим, если у вас большая иерархия объектов.

Подробнее о документах Apple вы можете прочитать здесь: http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CoreData/Articles/cdMemory.html.

Ответ 3

Чтобы помочь другим, имеющим ту же проблему, и усилить ответ Steff выше, вероятной причиной этой ошибки является то, что вы пытаетесь выпустить NSManagedObject.

Ответ 4

Я видел много забавных поведений с CoreData на iPhone, которые были решены путем сброса содержимого и настроек в симуляторе iPhone.

Ответ 5

Я знаю, что это старина, но у меня была такая же проблема, поэтому я подумал, что добавлю свою тупость в том, как я решил проблему, мой был вызван вручную выпуском управляемого объекта в модальном представлении, я удалил вызовы релиза и все работает нормально:) в соответствии с документами вы не должны вручную пытаться и выпускать управляемые объекты, так как контекст будет следить за всем этим. В любом случае, мой опыт, выполните поиск через свой код для перевыпущенных значений.

Ответ 6

Вы должны установить кеш FRC равным nil

Ответ 7

Я решил подобную проблему, убедившись, что объект извлечен, поэтому в примере выше:

if ( message == nil ) {
    message = [NSEntityDescription insertNewObjectForEntityForName:@"MailMessage" inManagedObjectContext:self.managedObjectContext];
} else {
    NSError *error = nil;
    message = (MailMessage *)[managedObjectContext existingObjectWithID:[message objectID] error:&error];
}