iphone - -[ClassRoster Controller WillChangeContent :]: message sent to deallocated instance

标签 iphone core-data memory-management

我知道这些错误是特定于应用程序的,并且几乎总是由于过度释放对象造成的。我只是无法发现它,而且我读过的调试技巧还没有为我解决问题。

根据this debugging advice ,我的“违规对象”被分配在此代码块中(位于 AddClass.m 中):

 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    if (indexPath.row == 1) {

        ClassRoster *classRoster = [[ClassRoster alloc] init];
        classRoster.managedObjectContext = managedObjectContext;
        classRoster.newClass = self.newClass;

        classRoster.title = @"Class Roster";
        [self.navigationController pushViewController:classRoster animated:YES];
        [classRoster release];

    }
}

但是,我不明白有问题的对象是如何来自这里的。我相信我正在适本地释放 classRoster 并且没有分配其他任何东西。

错误消息清楚地表明程序正在尝试更新我的 classRoster TableViewController 中的对象。这是有道理的,因为当我试图在 classRoster 的DetailViewController (AddStudent.m) 中保存一个对象时,发生了崩溃,当选择 classRoster 中的对象时,该对象就会被推送。

为了提供此问题的更广泛背景,我使用 Core Data 并(如您从上面的代码中看到的)在 View 之间传递单个 managedObjectContext 以便编辑和保存列表类(class)及其相关类(class)名册。我正在使用 [managementObjectContext rollback] 取消更改。

值得一提的是,AddStudent.m 中的 save 方法使用用户输入的字符串更新新创建的学生对象,然后通过 [class addStudentObject:student 将该学生对象添加到其父类对象中]。然后使用 [delegate addStudent:self didFinishWithSave:YES] 弹出detailViewController (AddStudent.m)。返回到 ClassRoster.m 后,managementObjectContext 被保存。

如果您认为我的核心数据管理可能存在问题,请告诉我您希望看到哪些代码。这是我的第一个应用程序,因此我很高兴犯了很多愚蠢的错误!

更新:

我已经研究了导致崩溃的操作顺序。如果我执行以下操作,我总是会因问题主题行中的错误而崩溃:

  1. 选择一个现有的类对象(按下其 AddClassDetailViewController)
  2. 选择查看类(class)名单
  3. 点击后退按钮返回到类对象detailView
  4. 选择再次查看类(class)名单
  5. 选择添加新学生或选择现有学生对象
  6. 选择保存

在以下堆栈跟踪中,断行由“BREAK >>”标记:

0x01e8c2f0  <+0000>  push   %ebp
0x01e8c2f1  <+0001>  mov    %esp,%ebp
0x01e8c2f3  <+0003>  push   %edi
0x01e8c2f4  <+0004>  push   %esi
0x01e8c2f5  <+0005>  push   %ebx
0x01e8c2f6  <+0006>  sub    $0x5c,%esp
0x01e8c2f9  <+0009>  call   0x1e8c2fe <___forwarding___+14>
0x01e8c2fe  <+0014>  pop    %ebx
0x01e8c2ff  <+0015>  mov    0xc(%ebp),%esi
0x01e8c302  <+0018>  test   %esi,%esi
0x01e8c304  <+0020>  je     0x1e8c620 <___forwarding___+816>
0x01e8c30a  <+0026>  mov    0x8(%ebp),%eax
0x01e8c30d  <+0029>  add    $0x4,%eax
0x01e8c310  <+0032>  mov    0x8(%ebp),%edx
0x01e8c313  <+0035>  mov    0x4(%edx),%edx
0x01e8c316  <+0038>  mov    %edx,-0x30(%ebp)
0x01e8c319  <+0041>  mov    0x4(%eax),%eax
0x01e8c31c  <+0044>  mov    %eax,-0x2c(%ebp)
0x01e8c31f  <+0047>  mov    -0x30(%ebp),%ecx
0x01e8c322  <+0050>  mov    %ecx,(%esp)
0x01e8c325  <+0053>  call   0x1f0a11e <dyld_stub_object_getClass>
0x01e8c32a  <+0058>  mov    %eax,(%esp)
0x01e8c32d  <+0061>  call   0x1f09e5a <dyld_stub_class_getName>
0x01e8c332  <+0066>  mov    %eax,-0x28(%ebp)
0x01e8c335  <+0069>  movl   $0xa,-0x34(%ebp)
0x01e8c33c  <+0076>  cld    
0x01e8c33d  <+0077>  lea    0x73a30(%ebx),%edi
0x01e8c343  <+0083>  mov    %eax,%esi
0x01e8c345  <+0085>  mov    $0xa,%ecx
0x01e8c34a  <+0090>  repz cmpsb %es:(%edi),%ds:(%esi)
0x01e8c34c  <+0092>  mov    $0x0,%eax
0x01e8c351  <+0097>  je     0x1e8c35d <___forwarding___+109>
0x01e8c353  <+0099>  movzbl -0x1(%esi),%eax
0x01e8c357  <+0103>  movzbl -0x1(%edi),%ecx
0x01e8c35b  <+0107>  sub    %ecx,%eax
0x01e8c35d  <+0109>  test   %eax,%eax
0x01e8c35f  <+0111>  jne    0x1e8c3a7 <___forwarding___+183>
0x01e8c361  <+0113>  mov    0x95d46(%ebx),%eax
0x01e8c367  <+0119>  cmpb   $0x0,(%eax)
0x01e8c36a  <+0122>  jne    0x1e8c680 <___forwarding___+912>
0x01e8c370  <+0128>  mov    -0x2c(%ebp),%edx
0x01e8c373  <+0131>  mov    %edx,(%esp)
0x01e8c376  <+0134>  call   0x1f0a214 <dyld_stub_sel_getName>
0x01e8c37b  <+0139>  mov    -0x30(%ebp),%ecx
0x01e8c37e  <+0142>  mov    %ecx,0x10(%esp)
0x01e8c382  <+0146>  mov    %eax,0xc(%esp)
0x01e8c386  <+0150>  mov    -0x28(%ebp),%eax
0x01e8c389  <+0153>  add    $0xa,%eax
0x01e8c38c  <+0156>  mov    %eax,0x8(%esp)
0x01e8c390  <+0160>  lea    0x9d822(%ebx),%eax
0x01e8c396  <+0166>  mov    %eax,0x4(%esp)
0x01e8c39a  <+0170>  movl   $0x3,(%esp)
0x01e8c3a1  <+0177>  call   0x1eb3040 <CFLog>
0x01e8c3a6  <+0182>  int3   
BREAK >> 0x01e8c3a7  <+0183>  movl   $0x11,-0x38(%ebp)
0x01e8c3ae  <+0190>  cld    
0x01e8c3af  <+0191>  lea    0x79590(%ebx),%edi
0x01e8c3b5  <+0197>  mov    -0x28(%ebp),%esi
0x01e8c3b8  <+0200>  mov    $0x11,%ecx
0x01e8c3bd  <+0205>  repz cmpsb %es:(%edi),%ds:(%esi)
0x01e8c3bf  <+0207>  mov    $0x0,%eax
0x01e8c3c4  <+0212>  je     0x1e8c3d0 <___forwarding___+224>
0x01e8c3c6  <+0214>  movzbl -0x1(%esi),%eax
0x01e8c3ca  <+0218>  movzbl -0x1(%edi),%ecx
0x01e8c3ce  <+0222>  sub    %ecx,%eax
0x01e8c3d0  <+0224>  mov    -0x30(%ebp),%edx
0x01e8c3d3  <+0227>  mov    %edx,-0x24(%ebp)
0x01e8c3d6  <+0230>  test   %eax,%eax
0x01e8c3d8  <+0232>  jne    0x1e8c3e0 <___forwarding___+240>
0x01e8c3da  <+0234>  mov    0x4(%edx),%ecx
0x01e8c3dd  <+0237>  mov    %ecx,-0x24(%ebp)
0x01e8c3e0  <+0240>  mov    0xa1dbe(%ebx),%esi
0x01e8c3e6  <+0246>  mov    -0x24(%ebp),%eax
0x01e8c3e9  <+0249>  mov    %eax,(%esp)
0x01e8c3ec  <+0252>  call   0x1f0a11e <dyld_stub_object_getClass>
0x01e8c3f1  <+0257>  mov    %esi,0x4(%esp)
0x01e8c3f5  <+0261>  mov    %eax,(%esp)
0x01e8c3f8  <+0264>  call   0x1f09e72 <dyld_stub_class_respondsToSelector>
0x01e8c3fd  <+0269>  test   %al,%al
0x01e8c3ff  <+0271>  je     0x1e8c580 <___forwarding___+656>
0x01e8c405  <+0277>  mov    -0x2c(%ebp),%edx
0x01e8c408  <+0280>  mov    %edx,0x8(%esp)
0x01e8c40c  <+0284>  mov    %esi,0x4(%esp)
0x01e8c410  <+0288>  mov    -0x24(%ebp),%ecx
0x01e8c413  <+0291>  mov    %ecx,(%esp)
0x01e8c416  <+0294>  call   0x1f0a0ee <dyld_stub_objc_msgSend>
0x01e8c41b  <+0299>  mov    %eax,-0x20(%ebp)
0x01e8c41e  <+0302>  mov    %eax,-0x1c(%ebp)
0x01e8c421  <+0305>  test   %eax,%eax
0x01e8c423  <+0307>  je     0x1e8c5ac <___forwarding___+700>
0x01e8c429  <+0313>  mov    0xa1df6(%ebx),%eax
0x01e8c42f  <+0319>  mov    %eax,0x4(%esp)
0x01e8c433  <+0323>  mov    -0x1c(%ebp),%edx
0x01e8c436  <+0326>  mov    %edx,(%esp)
0x01e8c439  <+0329>  call   0x1f0a0ee <dyld_stub_objc_msgSend>
0x01e8c43e  <+0334>  mov    (%eax),%edx
0x01e8c440  <+0336>  mov    0x18(%edx),%eax
0x01e8c443  <+0339>  shr    $0x16,%eax
0x01e8c446  <+0342>  and    $0x1,%eax
0x01e8c449  <+0345>  cmp    0xc(%ebp),%eax
0x01e8c44c  <+0348>  je     0x1e8c498 <___forwarding___+424>
0x01e8c44e  <+0350>  lea    0x6eaee(%ebx),%eax
0x01e8c454  <+0356>  lea    0x7979f(%ebx),%esi
0x01e8c45a  <+0362>  mov    0xc(%ebp),%ecx
0x01e8c45d  <+0365>  test   %ecx,%ecx
0x01e8c45f  <+0367>  mov    %eax,%edi
0x01e8c461  <+0369>  cmove  %esi,%edi
0x01e8c464  <+0372>  testb  $0x40,0x1a(%edx)
0x01e8c468  <+0376>  cmovne %eax,%esi
0x01e8c46b  <+0379>  mov    -0x2c(%ebp),%ecx
0x01e8c46e  <+0382>  mov    %ecx,(%esp)
0x01e8c471  <+0385>  call   0x1f0a214 <dyld_stub_sel_getName>
0x01e8c476  <+0390>  mov    %edi,0x10(%esp)
0x01e8c47a  <+0394>  mov    %esi,0xc(%esp)
0x01e8c47e  <+0398>  mov    %eax,0x8(%esp)
0x01e8c482  <+0402>  lea    0x9d852(%ebx),%eax
0x01e8c488  <+0408>  mov    %eax,0x4(%esp)
0x01e8c48c  <+0412>  movl   $0x4,(%esp)
0x01e8c493  <+0419>  call   0x1eb3040 <CFLog>
0x01e8c498  <+0424>  mov    -0x20(%ebp),%eax
0x01e8c49b  <+0427>  mov    %eax,0x8(%esp)
0x01e8c49f  <+0431>  mov    0xa1dba(%ebx),%eax
0x01e8c4a5  <+0437>  mov    %eax,0x4(%esp)
0x01e8c4a9  <+0441>  mov    0xa1e76(%ebx),%eax
0x01e8c4af  <+0447>  mov    %eax,(%esp)
0x01e8c4b2  <+0450>  call   0x1f0a0ee <dyld_stub_objc_msgSend>
0x01e8c4b7  <+0455>  mov    %eax,%edi
0x01e8c4b9  <+0457>  mov    0xa1dde(%ebx),%eax

最佳答案

以下是更有可能的情况:

  • 有一些事情 instanceVariable = [NSArray arrayWithObjects:..., nil];
  • NSArray 没有被保留,因此它在运行循环结束时被释放。
  • 有东西敲击了该行。 NSArray 的内存被重用来创建 ClassRoster 对象。
  • 您退出 ClassRoster,它就会被释放并取消分配。
  • 有东西尝试访问instanceVariable。它指向以前是 NSArray 的内存,但现在已被 ClassRoster 覆盖。

尝试设置环境变量 NSZombieEnabled=YES(在“项目”->“编辑事件可执行文件”中)。您还可以设置 NSDallocateZombies=NO,但 AIUI 这是默认设置。

完成调试后将其关闭。

编辑:哎呀(我应该意识到你有僵尸,并查看了方法名称)。

如果您在调试器中运行它(您可能需要激活断点),它应该停在名为controllerWillChangeContent:的地方。也许您的 ClassRoster 被设置为某件事的委托(delegate),并且在释放后正在获取委托(delegate)回调?我总是在 dealloc 中将相关委托(delegate)设置为 nil 以防止出现此类问题。

关于iphone - -[ClassRoster Controller WillChangeContent :]: message sent to deallocated instance,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3479369/

相关文章:

ios - 蓝牙扫描在后台不工作

ios - 为什么我的委托(delegate)方法从未被调用过?

mysql - MariaDB max_heap_table_size 是动态分配的吗?

ios - Swift 中 '_ in print()' 是什么意思?

iphone - UITableView - 滚动到下一页后,多个部分会重复(使用 Parse)

iphone - 如何在 iPad 应用程序中显示 GridView 等数据

ios - 核心数据轻量级迁移而不会在启动时被杀死

ios - 查找表格 View 中所有数字的平均值

c++ - 连续分配多维数组

c++ - double 组和堆损坏