(注意:我之前在我的项目的上下文中提出了这个问题,但我现在已经在一个测试项目中重新创建了崩溃。任何帮助告诉我我做错了什么将不胜感激。)
从另一个模态视图控制器调用 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,如下所示。(请注意,您需要将地址簿框架添加到目标。)这是整个程序...
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