代码之家  ›  专栏  ›  技术社区  ›  Mads Mobæk

核心数据崩溃,其中一个实体的exc-bad-access

  •  4
  • Mads Mobæk  · 技术社区  · 15 年前

    希望有人能帮助我调试这个问题,因为只有exc_bad_访问是我收到的唯一错误。我也试过打开nszombienabled,但据我所知,没有更多的信息。

    问题。我有四个实体:

    A->B->C->D

    其中箭头表示集合:“A”包含与“B”的A对多关系、“B”A对与“C”的多关系等,用于创建我使用的实体:

    id dto = [NSEntityDescription insertNewObjectForEntityForName:@"A" 
        inManagedObjectContext:context];
    NSLog(@"DTO: %@", dto);
    

    这似乎适用于A、B和C。但是,当在实体D上使用它时,应用程序会崩溃,无法访问exc-b a d-u。当访问对象时,似乎出现了这个问题,因为当注释nslog和其他访问dto对象的方法时,程序成功运行。

    更新:

    控制台输出

    GNU gdb 6.3.50-20050815 (Apple version gdb-1346) (Fri Sep 18 20:40:51 UTC 2009)
    Copyright 2004 Free Software Foundation, Inc.
    GDB is free software, covered by the GNU General Public License, and you are
    welcome to change it and/or distribute copies of it under certain conditions.
    Type "show copying" to see the conditions.
    There is absolutely no warranty for GDB.  Type "show warranty" for details.
    This GDB was configured as "x86_64-apple-darwin".sharedlibrary apply-load-rules all
    Attaching to process 3100.
    Program received signal:  “EXC_BAD_ACCESS”.
    warning: Unable to restore previously selected frame.
    No memory available to program now: unsafe to call malloc
    warning: check_safe_call: could not restore current frame
    
    Data Formatters temporarily unavailable, will re-try after a 'continue'. (Not safe to call dlopen at this time.)
    warning: Unable to restore previously selected frame.
    

    叠加
    堆栈跟踪非常大(?),调试时加载“62826堆栈帧”。显示其中的一部分: alt text http://i50.tinypic.com/2qrzxi1.png alt text http://i49.tinypic.com/iedoj5.png
    第8-41行重复到第62500帧周围。

    2 回复  |  直到 15 年前
        1
  •  9
  •   coneybeare    15 年前

    所以每当有这么多的堆栈帧时,就意味着存在某种无限递归。我的猜测是,当创建一个D对象时,有一些代码会自动创建其他的东西,而这反过来又会创建另一个D,并且有一个未终止的循环。我首先检查任何键值观察器或nsmanagedObject重写

        2
  •  0
  •   Aaron    15 年前

    看起来您需要保留新对象。这个 description 在该方法中,声明返回的对象是自动释放的,这意味着您的对象可能会在您有机会使用它之前被释放。将代码更改为如下所示:

    id dto = [[NSEntityDescription insertNewObjectForEntityForName:@"A" 
        inManagedObjectContext:context] retain];
    NSLog(@"DTO: %@", dto);
    

    完成后一定要释放对象,以避免内存泄漏。如果在DTO超出范围时完成对对象的处理(或者如果它将由另一个对象保留),则可以自动释放它,以便 autorelease pool 帮你保管好:

    id dto = [[[NSEntityDescription insertNewObjectForEntityForName:@"A" 
        inManagedObjectContext:context] retain] autorelease];