(注:以前、プロジェクトのコンテキストでこの質問を提出しましたが、テストプロジェクトでクラッシュを再現しました。間違っていることを教えてくれると助かります。)
別のモーダルビューコントローラーからABPeoplePickerを呼び出すと、クラッシュが発生します。具体的には、メインウィンドウにはmyVCをロードするNavControllerがあります。次に、myVCは、コントローラーを含むモーダルNavControllerをロードし、ABPeoplePickerを呼び出します。このデモプログラムでは、ABPeoplePickerが実行されるまでユーザーの介入は必要ありません。
ピープルピッカーの検索ボックスを使用して、結果のピープルの1つを選択すると、クラッシュが発生します。(シミュレーターを使用する場合は、プログラムを実行する前に連絡先に人を追加する必要があります。)プログラムは戻りますが、2つのモーダル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を変更してコントローラーを呼び出します。次に、次のように2つの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