Странный сбой при представлении модального UIViewController

Я видел этот краткий отчет несколько раз. Это чрезвычайно случайный и редкий, и я не могу этого понять. Все, что я делаю, представляет собой modal view controller, используя следующий код

ComposeController *newcontrol = [[ComposeController alloc]initWithMode:1 withNIB:@"ComposeController"]; newcontrol.delegate = self; UINavigationController *holder = [[UINavigationController alloc] initWithRootViewController:newcontrol]; [self presentViewController:holder animated:YES completion:NULL]; 

Как-то это приводит к этому совершенно случайно:

 OS Version: iPhone OS 6.1 (10B143) Report Version: 104 Exception Type: SIGSEGV Exception Codes: SEGV_ACCERR at 0x9 Crashed Thread: 0 Thread 0 Crashed: 0 libobjc.A.dylib 0x3b25c5d0 objc_msgSend + 16 1 CoreFoundation 0x334ba73f -[__NSPlaceholderArray initWithObjects:count:] + 271 2 CoreFoundation 0x334bae09 +[NSArray arrayWithObject:] + 45 3 UIKit 0x353e80ab -[UIWindow _rotationViewControllers] + 51 4 UIKit 0x353e7fe3 -[UIViewController viewControllerForRotation] + 91 5 UIKit 0x353e7f39 -[UIViewController _visibleView] + 97 6 UIKit 0x3546c05b -[UIWindowController transition:fromViewController:toViewController:target:didEndSelector:] + 2483 7 UIKit 0x3546afab -[UIViewController presentViewController:withTransition:completion:] + 3399 8 MyApp 0x00046e97 -[Inbox composeHit] (Inbox.m:207) 

У меня такая же проблема довольно последовательно. Кажется, это связано с тем, что я представляю контроллер модального представления от popover, который не очень хорошо протестирован и вызывает ошибку в коде Apple. Ошибка заключается в том, что UIKit хранит неиспользуемую ссылку на мой контроллер просмотра, который уже уволен и освобожден, поэтому позже ссылка будет удалена. Мое обходное решение заключается в том, чтобы избежать представления модальных VC из popover или сохранить все такие VC самостоятельно на неопределенный срок (в переменной-члене или в некоторых таких).

Ниже приведены подробные сведения.

Вот код, который я использовал, чтобы вызвать проблему.

 -(void) handlePinchFromCell:(AMPSupportingPhotoCell*) cell { UIViewController * vc = [[UIViewController alloc] init]; // UIViewController #0 [self presentViewController:vc animated:YES completion:nil]; [self performSelector:@selector(dismiss:) withObject:vc afterDelay:2]; } -(void) dismiss:(UIViewController*)vc { [self dismissViewControllerAnimated:YES completion:^(){NSLog(@"-------");}]; } 

Этот код является частью UIViewController # 1, который находится внутри UIPopoverController, который выскочил из другого UIViewController # 2, который сам представляет собой еще один вид UIViewController # 3. Сбой происходит после закрытия popover, диспетчер № 2 отклоняется.

Если я включу Zombies, я получаю одну и ту же трассировку стека, но с сообщением:

 2013-03-13 20:04:24.681 Mercury[16698:19d03] handlePinchFromCell: a225710 2013-03-13 20:04:27.083 Mercury[16698:19d03] ------- 2013-03-13 20:04:31.606 Mercury[16698:19d03] *** -[UIViewController retain]: message sent to deallocated instance 0xa225710 

Итак, обратите внимание, что VC # 0 получил выделенную, представленную, освобожденную через 2 секунды, освобожденную, и все же есть еще болтливая ссылка на нее где-то в коде Apple. Когда popover закрыт и VC # 2 уволен, все дело рушится, пытаясь получить доступ к освобожденному VC. Я вполне уверен, что это ошибка Apple. Я также предполагаю, что это связано с представлением VC из popover, поэтому, если вы держитесь подальше от этого или сами сохраните VC, вы должны быть в порядке.

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

 2013-03-13 20:12:53.883 Mercury[16735:19d03] handlePinchFromCell: 16d54da0 2013-03-13 20:12:56.285 Mercury[16735:19d03] ------- 2013-03-13 20:13:03.481 Mercury[16735:19d03] handlePinchFromCell: a2565f0 2013-03-13 20:13:03.481 Mercury[16735:19d03] *** -[UIViewController isKindOfClass:]: message sent to deallocated instance 0x16d54da0 (lldb) bt * thread #1: tid = 0x1f03, 0x017f8a97 CoreFoundation`___forwarding___ + 295, stop reason = EXC_BREAKPOINT (code=EXC_I386_BPT, subcode=0x0) frame #0: 0x017f8a97 CoreFoundation`___forwarding___ + 295 frame #1: 0x017f894e CoreFoundation`_CF_forwarding_prep_0 + 14 frame #2: 0x00c42f90 UIKit`-[UIWindowController transition:fromViewController:toViewController:target:didEndSelector:] + 907 frame #3: 0x00a40ee3 UIKit`-[UIViewController presentViewController:withTransition:completion:] + 4521 frame #4: 0x00a41167 UIKit`-[UIViewController presentViewController:animated:completion:] + 112 frame #5: 0x0006c32d Mercury`-[AMPSupportingPhotosViewController handlePinchFromCell:](self=0x16d55360, _cmd=0x0007a64a, cell=0x0a22a2a0) + 205 at AMPSupportingPhotosViewController.m:184 frame #6: 0x015336b0 libobjc.A.dylib`-[NSObject performSelector:withObject:] + 70 frame #7: 0x0006f317 Mercury`-[AMPSupportingPhotoCell handlePinch:](self=0x0a22a2a0, _cmd=0x00efb0db, sender=0x0a2504a0) + 215 at AMPSupportingPhotoCell.m:53 frame #8: 0x00c2185a UIKit`_UIGestureRecognizerSendActions + 139 

Попробуйте сделать это

[держатель pushViewController: newcontrol анимированный: ДА завершение: NULL];

Interesting Posts
Давайте будем гением компьютера.