[英]dismissViewControllerAnimated is called but ViewController is not dismissed
[英]Crash in ABPeoplePicker when called from another modal viewcontroller and both dismissed
(注意:我之前在項目上下文中提出了這個問題,但是現在我已經在測試項目中重新創建了崩潰。如果能幫助我告訴我我做錯了什么,將不勝感激。)
從另一個模式視圖控制器調用ABPeoplePicker時發生崩潰。 具體來說,主窗口有一個NavController,可加載myVC。 然后,myVC加載包含我的控制器的模態NavController,然后調用ABPeoplePicker。 在此演示程序中,直到ABPeoplePicker運行才需要用戶干預。
如果您使用人員選擇器中的搜索框,然后選擇結果人員之一,則會發生崩潰。 (如果使用模擬器,則需要在運行程序之前在“聯系人”中添加一個人。)程序返回,但是在關閉兩個模式VC時,出現斷言錯誤崩潰。 每次都在iphone,ipad和模擬器上同時發生。 這似乎是很正常的事情,所以我很難相信這是一個真正的錯誤。 崩潰消息是:
-[ABMembersSearchDisplayController setActive:animated:],/ SourceCache / UIKit_Sim / UIKit-1448.69 / UISearchDisplayController.m:589 2011-01-31 13:51:11.903 testcrasher2 [26044:207] *斷言失敗,因為未捕獲異常NSInternalInconsistencyException',原因:“搜索內容導航控制器不得在-setActive:YES和-setActive:NO之間切換”
為了演示,在一個新的Xcode iPhone Window應用程序中,我修改了didFinishLaunchingWithOptions來調用我的控制器。 然后,我創建兩個VC,如下所示。 (請注意,您需要將Addressbook框架添加到目標中。)這是整個程序...
AppDelegate.didFinishLaunchingWithOptions:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
myViewController *detailViewController = [[myViewController alloc] init];
// Set the navigation controller as the window's root view controller and display.
UINavigationController * navController = [[UINavigationController alloc] initWithRootViewController: detailViewController];
self.window.rootViewController = navController;
[self.window makeKeyAndVisible];
[detailViewController release];
[navController release];
return YES;
}
myViewController.h:
@interface myViewController : UIViewController<addDelegate>{
}
@end
myViewController.m:
#import "myViewController.h"
#import "AddNewViewController.h"
@implementation myViewController
- (void)controllerDidFinish:(addNewViewController *)controller {
[self dismissModalViewControllerAnimated:YES];
}
-(void) viewWillAppear:(BOOL)animated {
[super viewWillAppear: animated];
addNewViewController *addController = [[addNewViewController alloc] init];
addController.delegate = self;
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:addController];
[self presentModalViewController:navController animated:YES];
[navController release];
[addController release];
}
@end
AddNewViewController.h:
#import <AddressBookUI/AddressBookUI.h>
@protocol addDelegate;
@interface addNewViewController : UIViewController < ABPeoplePickerNavigationControllerDelegate> {
id <addDelegate> delegate;
}
@property(nonatomic, assign) id <addDelegate> delegate;
@end
@protocol addDelegate <NSObject>
- (void)controllerDidFinish:(addNewViewController *)controller ;
@end
AddNewViewController.m:
#import "AddNewViewController.h"
@implementation addNewViewController
@synthesize delegate;
-(void) viewDidAppear:(BOOL)animated {
ABPeoplePickerNavigationController * peoplepicker = [[ABPeoplePickerNavigationController alloc] init] ;
peoplepicker.peoplePickerDelegate = self;
[self presentModalViewController:peoplepicker animated:YES];
[peoplepicker release];
}
#pragma mark AddressBook delegate methods
- (void)peoplePickerNavigationControllerDidCancel: (ABPeoplePickerNavigationController *)peoplePicker {
[self dismissModalViewControllerAnimated:YES];
}
- (BOOL)peoplePickerNavigationController: (ABPeoplePickerNavigationController *)peoplePicker
shouldContinueAfterSelectingPerson:(ABRecordRef)person {
[self.delegate controllerDidFinish:self ];
return NO; //EDIT: This MUST be YES or it will crash (see answer below)
}
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker
shouldContinueAfterSelectingPerson:(ABRecordRef)person
property:(ABPropertyID)property
identifier:(ABMultiValueIdentifier)identifier {
return NO;
}
@end
原來這是一個實際的錯誤。 的確如此,如果用戶在搜索中單擊某個人時對ABPeoplePicker進行了兩次ModalVC關閉,則會發生此崩潰。 幸運的是,有一個簡單的解決方法:在委托的shouldContinueAfterSelectingPerson中返回YES。 當您同時關閉選擇器時,返回YES或NO並不重要,它不會繼續,但是NO會崩潰而YES不會。 (與我的原始帖子的答案相同: ABPeoplePicker中的怪異崩潰 )
該錯誤實際上在您的代碼中。 花了我幾分鍾找到它,我將盡力解釋。
ABPeoplePickerNavigationController
當前以模態顯示。 此處發生的是ABPeoplePickerNavigationController
詢問其委托人(您的addNewViewController
)在選擇一個人后是否應繼續執行。 在等待您的addNewViewController
,您突然調用了自己協議的方法(在myViewController
),該方法試圖消除模式化addNewViewController
。 由於ABPeoplePickerNavigationController
仍處於打開狀態,因此您正在超越自己。
將您的ABPeoplePickerNavigationControllerDelegate方法的實現更改為:
- (BOOL)peoplePickerNavigationController: (ABPeoplePickerNavigationController *)peoplePicker
shouldContinueAfterSelectingPerson:(ABRecordRef)person {
// This line is new.
[self.navigationController dismissModalViewControllerAnimated:YES];
[self.delegate controllerDidFinish:self];
return NO;
}
您的崩潰將消失。 在處理UIViewControllers和UINavigationControllers的各層時,必須非常小心,以與顯示它們相反的順序將其關閉。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.