2009-08-05 1 views
14

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

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

Вот участок кода, который разваливается:

[Изменено]

 - (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:@""]]; 
} 
+0

Может быть, вы можете прокомментировать некоторые изменения в ваших атрибутах первым, и попробовать их одно- по одному, чтобы увидеть, какой из них вызывает сбой после изменения и сохранения. – digdog

+0

Кажется, это не вызвано ни одним из полей, я думаю, это должно быть связано с представлением модального представления ... Но я понятия не имею, почему. Все, что я делаю, представляет представление, а затем отклоняет его ... – kiyoshi

+0

Думаю, вы можете посмотреть на неправильную область. 1. Прокомментируйте ВСЕ код сохранения данных ядра выше. или просто добавьте «возврат» в самый верх, поэтому этот код никогда не запускается. ТЕСТ для краха. 2. Если авария не возникает, ОК, она должна быть в основных данных. Делайте все, но не вызывайте функцию сохранения, последние несколько строк. 3. Покажите нам много кода для этой функции, поскольку мне интересно, как вы заполняете сообщение, если оно не ноль. 4. Что такое консольное высказывание.Он должен дать вам более подробную информацию о том, что произошло. –

ответ

8

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

[managedObjectContext setRetainsRegisteredObjects:YES]; 

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

+0

У меня такая же проблема - также исправлена ​​директива, которую вы здесь включили. Что я не знаю ... мы ожидаем, что теперь мы вручную выпустим все сущности, управляемые этим моком? –

+1

Хотя это может исправить вашу проблему, ваши аргументы несколько ошибочны. Мой ответ ниже объясняет, почему save: вызывает вашу проблему и указывает на документы Apple. –

+0

Привет. несохраненные управляемые объекты освобождаются при вызове save. Новые управляемые объекты должны быть загружены из вашего контроллера результатов выборки. – stephen

0

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

+0

Запуск его на ipod touch, хотя, но я попробовал сбросить содержимое безрезультатно :( – kiyoshi

0

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

0

Вы должны установить кэш FRC на ноль

4

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

22

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

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

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

0

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

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