- [ClassRoster controllerWillChangeContent:]: сообщение отправлено на освобожденный экземпляр - PullRequest
2 голосов
/ 13 августа 2010

Я знаю, что эти ошибки очень специфичны для приложения и почти всегда из-за чрезмерного освобождения объекта. Я просто не могу определить это, и советы по отладке, которые я прочитал, еще не помогли мне.

В соответствии с этим советом по отладке , мой "объект-нарушитель" был размещен в этом блоке кода (расположен в 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. Это имеет смысл, потому что сбой произошел, когда я пытался сохранить объект в detailViewController (AddStudent.m) классаRoster, который активируется при выборе объекта в classRoster.

Чтобы дать более широкий контекст этой проблемы, я использую базовые данные и (как вы можете видеть из приведенного выше кода) передачу одного managedObjectContext между представлениями, чтобы редактировать и сохранять список классов и связанных с ними классов реестры. Я использую [managedObjectContext rollback] для отмены изменений.

Возможно, стоит упомянуть, что метод save внутри AddStudent.m обновляет вновь созданный объект ученика строками, введенными пользователем, а затем добавляет этот объект ученика в свой родительский объект класса с помощью [class addStudentObject:student]. DetailViewController (AddStudent.m) затем появляется с [delegate addStudent:self didFinishWithSave:YES]. При возврате к ClassRoster.m, managedObjectContext сохраняется.

Если вы считаете, что мое управление основными данными может быть проблемой, просто дайте мне знать, какой код вы хотели бы видеть. Это мое первое приложение, и поэтому я рад совершать множество глупых ошибок!

UPDATE:

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

  1. Выберите существующий объект класса (нажмите на его AddClass detailViewController)
  2. Выберите для просмотра списка классов
  3. Нажмите кнопку "Назад", чтобы вернуться к объекту класса detailView
  4. Выберите, чтобы снова просмотреть список класса
  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

Ответы [ 4 ]

2 голосов
/ 13 августа 2010

Вот что более вероятно:

  • Что-то делает instanceVariable = [NSArray arrayWithObjects:..., nil];
  • NSArray не был сохранен, поэтому он освобождается в конце цикла выполнения.
  • Что-то касается строки.Память NSArray повторно используется для создания объекта ClassRoster.
  • Вы выходите из ClassRoster, и он освобождается и освобождается.
  • Что-то пытается получить доступ к instanceVariable.Он указывает на память, которая раньше была NSArray, но теперь была перезаписана ClassRoster.

Попробуйте установить переменную среды NSZombieEnabled = YES (в Project -> Edit Active Executable).Вы также можете установить NSDeallocateZombies = NO, но AIUI это по умолчанию.

Отключите его, как только вы закончите отладку.

EDIT: Упс (я должен былпонял, что у вас есть зомби, и посмотрел на имя метода).

Если вы запустите его в отладчике (вам могут потребоваться активные точки останова), он должен остановиться на том, что называется controllerWillChangeContent:.Возможно, ваш ClassRoster назначается делегатом для чего-то и получает ответный вызов делегата после того, как он был освобожден?Я всегда устанавливаю для соответствующих делегатов значение nil в dealloc, чтобы избежать подобных проблем.

0 голосов
/ 26 августа 2011

просто была такая же проблема проблема была в том, что я освободил делегат вместо того, чтобы установить его на ноль

удачи!

0 голосов
/ 14 августа 2010

'Недопустимая попытка установить связь' myClass 'между объектами в разных контекстах'

Эта строка описывает проблему.Вы, вероятно, используете код из примера Apple, в котором вы правильно создали более одного NSManagedObjectContext?Возможно, код предлагал создать второй, чтобы вы могли легко отменить редактирование или что-то подобное?

В этом ваша проблема.Вы пытаетесь соединить два объекта, которые находятся в двух разных экземплярах NSManagedObjectContext.Считайте каждый NSManagedObjectContext песочницей, и вы не можете смешивать их.

Однако вам не нужно иметь более одного NSManagedObjectContext.Пример, который делает это, очень плохой пример.Одного NSManagedObjectContext более чем достаточно для любого однопоточного приложения.Удалите второй NSManagedObjectContext из вашего приложения, и эта проблема исчезнет.

Обновление

Я обнаружил ошибку.Вы не можете создать NSManagedObject с -init.Это не назначенный инициализатор для NSManagedObject.Вы должны либо создать его с помощью

-initWithEntity: insertIntoManagedObjectContext:

, либо использовать метод класса

+[NSEntityDescription insertNewObjectForEntityForName: inManagedObjectContext]

Это единственные два действительных способа создания нового NSManagedObject.]

Обновление

I Настоятельно предлагает вам использовать лучшие соглашения об именах, ClassRosterViewController гораздо более информативно.ClassRoster действительно звучит как объект данных.

Мое первоначальное предположение все еще остается где-то, как-то вы пытаетесь соединить два NSManagedObject экземпляра, которые не принадлежат одному и тому же NSManagedObjectContext.Либо у вас есть два экземпляра NSManagedObjectContext, либо вы создаете NSManagedObject без связанного NSManagedObjectContext.

Однако мои ответы основаны на сообщении об ошибке в вашем вопросе.Где вы видите ошибку, которая есть в вашем заголовке.Можете ли вы вставить этот стек трассировки?

0 голосов
/ 13 августа 2010

Не думаю, что вы переиздали экземпляр.

Мне кажется, что освобожденный экземпляр другого класса, но получает сообщение от ClassRoaster.

Можете ли вы опубликовать сообщение об ошибке и трассировку стека с момента сбоя приложения?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...