【问题标题】:Iphone Core Data crashing on SaveIphone Core Data 在保存时崩溃
【发布时间】:2010-11-16 21:09:44
【问题描述】:

我目前正在使用 Core Data 编写一个 Iphone 应用程序,并且在 [managedObjectContext save:&&error] 代码行期间出现EXC_BAD_ACCESS 错误。此崩溃仅在我修改某些字段后发生。更具体地说,我的实体有两个字符串字段(大约 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];
}

}

这是崩溃日志:

异常类型:EXC_BAD_ACCESS (SIGBUS) 异常代码:0x00000015 处的 KERN_PROTECTION_FAILURE 崩溃的线程:0 线程 0 崩溃: 0 libobjc.A.dylib 0x30011940 objc_msgSend + 20 1 核心数据 0x367f7d3e -[NSKnownKeysDictionary1 释放] + 82 2 CoreData 0x367f7cda -[NSKnownKeysDictionary1 版本] + 34 3 核心数据 0x3687eec4 -[NSManagedObject(_NSInternalMethods) _setOriginalSnapshot__:] + 40 4核心数据0x36821030-[NSManagedObjectContext(_NSInternalAdditions)_clearOriginalSnapshotAndInitializeRec:]+16 5 核心数据 0x368205f2 -[NSManagedObjectContext(_NSInternalAdditions)_didSaveChanges] + 958 6 核心数据 0x368133bc -[NSManagedObjectContext 保存:] + 412 7 Decome 0x0001fdd6 -[CreateMessageViewController actionSheet:clickedButtonAtIndex:] (CreateMessageViewController.m:163) 8 UIKit 0x30a6cbd8-[UIActionSheet(Private)_buttonClicked:] + 256 9 核心基础 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(内部)_sendActionsForEvents:withEvent:] + 528 14 UIKit 0x309a6e9c-[UIControl touchesEnded:withEvent:] + 452 15 UIKit 0x309a60d4-[UIWindow_sendTouchesForEvent:] + 520 16 UIKit 0x309a5464 -[UIWindow 发送事件:] + 108 17 UIKit 0x30936e3c -[UIApplication 发送事件:] + 400

感谢您的帮助。

更新:此外,即使程序崩溃,当我打开它备份时,数据已正确保存。所以 EXC_BAD_ACCESS 必须在保存至少足够远以存储在我认为的持久存储中之后发生。

如果我注释掉保存行,代码现在可以正常运行。但是在我关闭并退出后它不会保存。如果我在根视图控制器 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 在 -[NSManagedObjectContext(_NSInternalAdditions) _clearOriginalSnapshotAndInitializeRec:] () #5 0x368205f8 在 -[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";

它仍然崩溃。如果我将这两行都注释掉,但它不会崩溃。

因此,如果我呈现一个模态视图然后尝试编辑我的 NSOManagedObject 的 textArray 或 htmlString 字段,它似乎会崩溃...

这里是我展示视图的地方:

- (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. 注释掉上面所有的核心数据保存代码。或者只是在最顶部添加一个“return”调用,这样这段代码就永远不会运行。测试崩溃。 2.如果没有发生crash,OK,一定是在core data里面。做所有事情,但不要调用保存函数,最后几行。 3. 向我们展示这个函数的全部代码,因为我想知道如果它不是 nil,你是如何填充消息的。 4. 控制台在说什么。它应该为您提供有关发生的事情的更多详细信息。
  • 编辑了我的帖子以包含更多代码。如果我注释掉保存,它不会崩溃。如果 message 不为零,我将运行相同的代码,它只是修改我在推送视图控制器时传递给它的 MailMessage 对象。控制台说的是 EXC_BAD_ACCESS。

标签: iphone core-data exc-bad-access


【解决方案1】:

只有当对某个对象的更改(插入、更新、删除)处于未决状态时,您才能保证从上下文中保留对托管对象的访问权限。一旦您调用 save:,您可能会丢失对托管对象的引用。

虽然您在设置 setRetainsRegisteredObjects:YES 时不再收到错误消息,但您可能已经引入了内存管理问题,因为您将托管对象的生命周期设置为依赖于托管对象上下文的生命周期。如果您在整个应用程序中传递上下文,如果您的对象层次结构很大,这可能会变得相当大。

您可以在此处阅读更多 Apple 文档:https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/CoreData/MO_Lifecycle.html

【讨论】:

    【解决方案2】:

    我通过确保获取对象解决了类似的问题,因此对于上面的示例:

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

    【讨论】:

      【解决方案3】:

      虽然我不确定我是否解决了实际的根本原因,但已解决了问题。当我添加这一行时,错误已消除:

      [managedObjectContext setRetainsRegisteredObjects:YES];
      

      到我创建 managedObjectContext 的地方。所以我想这与保留计数有关。我猜想当模态视图出现时,实例变量可能会部分或暂时释放或者是什么?我不知道。无论如何,这个错误被消除了,程序现在可以正常工作了。

      【讨论】:

      • 我遇到了类似的问题 - 也通过您在此处包含的指令修复。我不知道的是......我们现在是否应该手动释放这个 moc 管理的每个实体?
      • 虽然这可能会纠正您的问题,但您的推理有些错误。我在下面的回答解释了为什么 save: 导致您的问题并指向 Apple 文档。
      • 嗨。调用 save 时释放未保存的托管对象。应该从您的获取结果控制器加载新的托管对象。
      【解决方案4】:

      您必须将 FRC 缓存设置为 nil

      【讨论】:

        【解决方案5】:

        只是为了帮助遇到同样问题的其他人,并加强 Steff 的上述回应,此错误的可能原因是您试图释放 NSManagedObject。

        【讨论】:

          【解决方案6】:

          我知道这是一个老歌,但我遇到了同样的问题,所以我想补充一下我是如何解决这个问题的,我的问题是由于在模态视图中手动释放托管对象引起的,我删除了释放调用并且一切正常:) 根据文档,无论如何您都不应该手动尝试释放托管对象,因为上下文会处理所有这些。无论如何,这就是我的经验,在您的代码中搜索过度发布的值。

          【讨论】:

            【解决方案7】:

            我在 iPhone 上看到过许多有趣的 CoreData 行为,这些行为都是通过在 iPhone 模拟器中重置内容和设置来解决的。

            【讨论】:

            • 虽然在 ipod touch 上运行它,但是尝试重置内容无济于事:(.
            猜你喜欢
            • 1970-01-01
            • 2016-12-12
            • 1970-01-01
            • 1970-01-01
            • 2012-05-02
            • 1970-01-01
            • 2016-10-27
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多