Странный сбой в ABPeoplePicker - PullRequest
0 голосов
/ 27 января 2011

Я использую ABPeoplePicker и получаю странный сбой:

Assertion failure in -[UISearchDisplayController setActive:animated:], 
/SourceCache/UIKit/UIKit-1447.6.4/UISearchDisplayController.m:589
2011-01-26 22:30:37.041 Watches[3784:307] 
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', 
reason: 'search contents navigation controller must not change between -setActive:YES and -setActive:NO

Сбой происходит после того, как пользователь использует поле поиска и затем выбирает результирующих кандидатов. PeoplePickerNavigationController моего делегата: shouldContinueAfterSelectingPerson: метод вызывается с соответствующей информацией для человека. Делегат сам по себе является модальным контроллером, поэтому он сохраняет информацию и обращается к своему родителю, который вызывает [self dismissModalViewControllerAnimated: NO], а затем возвращает обратно в стек ABPeoplePicker, возвращая NO для mustContinue.

Устанавливая точку останова в ViewWillAppear для родительской подпрограммы (отметка верхнего уровня), я вижу стек, который выглядит следующим образом:

#0  -[RunnerListTableViewController viewWillAppear:] (self=0x1cc650, _cmd=0x33bc6b5a, animated=1 '\001') at /Users/hughmackworth/develop/Watches/RunnerListTableViewController.m:61
#1  0x338e4fe4 in -[UINavigationController viewWillAppear:] ()
#2  0x3391a1e2 in -[UITabBarController viewWillAppear:] ()
#3  0x3396e280 in -[UIWindowController transition:fromViewController:toViewController:target:didEndSelector:] ()
#4  0x339dd36e in -[UIViewController _dismissModalViewControllerWithTransition:from:] ()
#5  0x339dc86e in -[UIViewController dismissModalViewControllerWithTransition:] ()
#6  0x339dc734 in -[UIViewController dismissModalViewControllerWithTransition:] ()
#7  0x339dc734 in -[UIViewController dismissModalViewControllerWithTransition:] ()
#8  0x339da668 in -[UIViewController dismissModalViewControllerAnimated:] ()
#9  0x000098c2 in -[RunnerListTableViewController runnerAddViewController:didAddRunners:] (self=0x1cc650, _cmd=0x29a86, runnerAddViewController=0x1dbf50, runners=0x45cb860) at /Users/hughmackworth/develop/Watches/RunnerListTableViewController.m:147
#10 0x0000d4a8 in -[RunnerAddNewViewController save:] (self=0x1dbf50, _cmd=0x3530e35b, runner=0x45c8c20) at /Users/hughmackworth/develop/Watches/RunnerAddNewViewController.m:174
#11 0x0000ce6c in -[RunnerAddNewViewController peoplePickerNavigationController:shouldContinueAfterSelectingPerson:] (self=0x1dbf50, _cmd=0x30549382, peoplePicker=0x35c87e0, person=0x455f2c0) at /Users/hughmackworth/develop/Watches/RunnerAddNewViewController.m:105
#12 0x35eabaea in -[ABPeoplePickerNavigationController showCardForPerson:withMemberCell:animate:forceDisableEditing:personViewController:] ()
#13 0x35eab978 in -[ABMembersViewController showCardForPerson:withMemberCell:animate:] ()
#14 0x35eab826 in -[ABMembersController showCardForPerson:withMemberCell:animate:] ()
#15 0x35eab76a in -[ABMembersController abDataSource:selectedPerson:atIndexPath:withMemberCell:animate:] ()
#16 0x35eab70e in -[ABMembersFilteredDataSource tableView:didSelectRowAtIndexPath:] ()
#17 0x3390483a in -[UITableView _selectRowAtIndexPath:animated:scrollPosition:notifyDelegate:] ()
#18 0x339c4612 in -[UITableView _userSelectRowAtPendingSelectionIndexPath:] ()

Затем я наблюдаю, как различные подпрограммы сворачиваются, пока не произойдет сбой, когда стек опустится до:

// removed assertion handling routines>>
4   UIKit              0x3394192b -[UISearchDisplayController setActive:animated:] + 986
5   AddressBookUI      0x35ee65d7 -[ABMembersController cancelSearchingAnimated:] + 26
6   AddressBookUI      0x35eab789 -[ABMembersController abDataSource:selectedPerson:atIndexPath:withMemberCell:animate:] + 80
7   AddressBookUI      0x35eab70f -[ABMembersFilteredDataSource tableView:didSelectRowAtIndexPath:] + 82
8   UIKit              0x3390483b -[UITableView _selectRowAtIndexPath:animated:scrollPosition:notifyDelegate:] + 662

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

Поскольку я не имею ничего общего с контроллером поиска внутри ABPeoplePicker, а также не изменяю его во время его активации или нет, я не вижу, как это исправить.

В качестве дополнительного примечания я замечаю случайную ошибку: CPSqliteStatementSendResults: прервано во время ввода в поле поиска. Есть мысли о том, что это значит?

Код делегата:

- (BOOL)peoplePickerNavigationController: (ABPeoplePickerNavigationController *)peoplePicker
      shouldContinueAfterSelectingPerson:(ABRecordRef)person {
    NSLog(@"got one from peoplepicker");
    if (ABRecordGetRecordType (person) == kABPersonType{ 

    Runner * newRunner = [Runner createRunnerFromAddrBookPerson: person];
    if (newRunner) {
            self.nameTextView.text = newRunner.Name;
            [self save:newRunner];
    }
    return NO;    //EDIT: MUST return YES or this will crash
}

- (void)save: (Runner *) runner { //send back last one added
    [self.delegate runnerAddViewController:self 
                             didAddRunners:[NSArray arrayWithObject:runner]];  
}

И код делегата родителя:

- (void)runnerAddViewController:(RunnerAddNewViewController *)runnerAddViewController 
                  didAddRunners:(NSArray *)runners {
    if (runners) {
           //stuff interacting with my model
    }
    // Dismiss the modal addRunner view controller
    [self dismissModalViewControllerAnimated:YES];
}

Любые подсказки или предложения по проведению экспериментов или где искать? Вызывается ли dismissModalVC из правильного места (для отклонения двух уровней)?

Ответы [ 2 ]

2 голосов
/ 18 февраля 2011

Оказывается, это фактическая ошибка. Если вы выполните двойное увольнение ModalVC в ABPeoplePicker, когда пользователь нажимает на человека в поиске, вы получите этот сбой. К счастью, существует простой обходной путь: верните YES в mustContinueAfterSelectingPerson вашего делегата. Поскольку вы одновременно отклоняете средство выбора, на самом деле не имеет значения, возвращаете ли вы ДА или НЕТ, оно не будет продолжаться, но НЕТ будет аварийно завершать работу, а ДА - нет.

0 голосов
/ 27 января 2011

Запустите с NSZombieEnabled, и я подозреваю, что вы замените ошибку подтверждения ошибкой, что к какому-либо объекту обращаются после его освобождения.

...