为什么 peoplePickerDelegate 没有正确获取代表的地址?

发布于 2024-12-19 15:36:34 字数 2306 浏览 3 评论 0原文

场景是我有多个视图想要调用地址簿。为了不在每个视图中重复委托的代码,我已将代码放在应用程序委托的标头和 .m 文件中,但在 2 个相应应用程序的底部使用“@interface AddressBookDelegate”和“@implementation AddressBookDelegate”委托 fiies-

@interface AddressBookDelegate : UIViewController <ABPeoplePickerNavigationControllerDelegate> {
AddressBookDelegate *addressBookDelegate;   
}
@property (nonatomic, retain) AddressBookDelegate *addressBookDelegate;
@end

然后

@implementation AddressBookDelegate
@synthesize addressBookDelegate;

- (void)peoplePickerNavigationControllerDidCancel: (ABPeoplePickerNavigationController *)peoplePicker 
{
    [self dismissModalViewControllerAnimated:YES];
}

- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person
{   
    [super dismissModalViewControllerAnimated:YES];

    ...get stuff from the Address Book...   

    return NO;
}

- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person 
                            property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier
{
    return NO;
}

在我的视图中我有以下代码:

addressBookDelegate = (AddressBookDelegate *) [[UIApplication sharedApplication] delegate];

ABPeoplePickerNavigationController *abPicker = [[ABPeoplePickerNavigationController alloc]init];    
abPicker.peoplePickerDelegate = self.addressBookDelegate;
[self presentModalViewController:abPicker animated:YES];
[abPicker release];

地址簿在所有视图中显示良好。但是,当我执行任何会调用委托的用户操作(例如地址簿的取消按钮)时,我会崩溃-

-[MyprogAppDelegate peoplePickerNavigationControllerDidCancel:]:无法识别的选择器发送到实例

它编译干净,没有警告。

当 peoplePickerDelegate 与视图本身不在物理上位于同一文件中时,如何连接 peoplePickerDelegate 以连接到地址委托代码?谢谢。

添加注意:当我使用调试器并停止在视图代码中的行时

abPicker.peoplePickerDelegate = addressBookDelegate;

,我看到 addressBookDelegate 的地址被声明为 MyprogAppDelegate 的地址,而不是我预期的 AddressBookDelegate 的地址。这让我认为地址簿委托代码的位移在应用程序委托文件中已关闭。

如果 AddressBookDelegate 取消委托代码在 AddressBookDelegate 中输入 1000 字节,那么我的应用程序实际上是将 1000 字节代码“输入”到 MyprogAppDelegate 中,因此崩溃。所以不知何故我没有正确设置 AddressBookDelegate 的寻址。无论如何,这就是我的看法......

The scenario is that I have more than one view that wants to invoke the Address Book. So as not to duplicate the code of the delegate in each view I have located the code in the App Delegate's header and .m file, but using an "@interface AddressBookDelegate" and "@implementation AddressBookDelegate" at the bottom of the 2 respective App Delegate fiies-

@interface AddressBookDelegate : UIViewController <ABPeoplePickerNavigationControllerDelegate> {
AddressBookDelegate *addressBookDelegate;   
}
@property (nonatomic, retain) AddressBookDelegate *addressBookDelegate;
@end

and

@implementation AddressBookDelegate
@synthesize addressBookDelegate;

- (void)peoplePickerNavigationControllerDidCancel: (ABPeoplePickerNavigationController *)peoplePicker 
{
    [self dismissModalViewControllerAnimated:YES];
}

- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person
{   
    [super dismissModalViewControllerAnimated:YES];

    ...get stuff from the Address Book...   

    return NO;
}

- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person 
                            property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier
{
    return NO;
}

Then in my views I have the following code:

addressBookDelegate = (AddressBookDelegate *) [[UIApplication sharedApplication] delegate];

ABPeoplePickerNavigationController *abPicker = [[ABPeoplePickerNavigationController alloc]init];    
abPicker.peoplePickerDelegate = self.addressBookDelegate;
[self presentModalViewController:abPicker animated:YES];
[abPicker release];

The Address Book displays fine in all views. But when I take any user action that would invoke a delegate, like the Address Book's Cancel button, I crash-

-[MyprogAppDelegate peoplePickerNavigationControllerDidCancel:]: unrecognized selector sent to instance

It compiles clean, no Warnings.

How do I wire-up the peoplePickerDelegate to connect to the Address Delegate code when it is not physically in the same file as the view itself ? Thx.

ADDED NOTE: when I use the debugger and stop on the line

abPicker.peoplePickerDelegate = addressBookDelegate;

in the view code, I see that the address for the addressBookDelegate is stated to be the address of the MyprogAppDelegate, not AddressBookDelegate as I might have expected. That makes me think the displacement to the address book delegate code is off within the App Delegate file.

If the AddressBookDelegate Cancel Delegate code were say 1000 bytes into the AddressBookDelegate, my app is actually "entering" the code 1000 bytes into MyprogAppDelegate, and so crashes. So somehow I am not setting up the addressing of the AddressBookDelegate correctly. That's my take on it anyway...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

巷子口的你 2024-12-26 15:36:35

最终我未能使上述任何建议都按预期执行。我不得不缩短时间并继续前进,因此我在每个视图中复制了代码。我将再次讨论这个问题,因为我确信它可以通过比我结束时更基于对象的方式来完成。

In the end I was not able to make any of the above suggestions perform as hoped for. I had to cut time and move on so I duplicated the code in each view. I will revisit this another time, as I am sure it can be done in a more object based way than I ended it doing it.

自演自醉 2024-12-26 15:36:34

您的代码假定您的 appdelegate (MyprogAppDelegate) 实现方法 peoplePickerNavigationControllerDidCancel

因此,MyprogAppDelegate 中的代码应该如下所示:

@implementation MyprogAppDelegate
@synthesize ...;

#pragma mark -
#pragma mark Application lifecycle
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    


    return YES;
}

- (void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker{

}

Your code assumes that your appdelegate (MyprogAppDelegate) implements method peoplePickerNavigationControllerDidCancel.

So, your code in MyprogAppDelegate should be something like this:

@implementation MyprogAppDelegate
@synthesize ...;

#pragma mark -
#pragma mark Application lifecycle
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    


    return YES;
}

- (void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker{

}
攒一口袋星星 2024-12-26 15:36:34

编辑好的,整个第一个答案已经被扔掉了。带着一些警告,这仍然有点盲目,但我认为它会更接近有用。不过,有些想法确实延续了下来。

  1. 很可能不需要单独的类来充当您的ABPeoplePickerNavigationControllerDelegate。很可能,它应该是与您的代码位于底部的同一个类(调用 presentModalViewController:animated:。由于我不知道那是什么控制器,所以我将只调用它 MyViewController 供参考。您希望该视图控制器成为委托的原因是,在您的委托方法中,您需要能够关闭具有地址簿的模式视图控制器。

  2. 肯定不希望程序的UIApplicationDelegate成为ABPeoplePickerNavigationControllerDelegate。正如您自己所说,peoplePickerDelegate 必须是 UIViewController

所以,到MyViewController。首先,界面:

/* MyViewController.h */

@interface MyViewController : UIViewController<ABPeoplePickerNavigationControllerDelegate>
...
@end

您的控制器可能继承自 UIViewController 的后代(例如表视图控制器或类似的东西) - 不应该改变,唯一应该改变的是将 ABPeoplePickerNavigationControllerDelegate 添加到已实施协议的列表。

现在,要实现该功能:

/* MyViewController.m */

@implementation MyViewController

...
- (void) whateverMethodIsDisplayingTheAddressBook
{
    ABPeoplePickerNavigationController *abPicker = [[ABPeoplePickerNavigationController alloc]init];    
    abPicker.peoplePickerDelegate = self; // This view controller is the delegate
    [self presentModalViewController:abPicker animated:YES];
    [abPicker release];
}

...

- (void)peoplePickerNavigationControllerDidCancel: (ABPeoplePickerNavigationController *)peoplePicker 
{
    [self dismissModalViewControllerAnimated:YES];
}

- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker
      shouldContinueAfterSelectingPerson:(ABRecordRef)person
{   
    [super dismissModalViewControllerAnimated:YES];

    ...get stuff from the Address Book...   

    return NO;
}

- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker
      shouldContinueAfterSelectingPerson:(ABRecordRef)person
                                property:(ABPropertyID)property
                              identifier:(ABMultiValueIdentifier)identifier
{
    return NO;
}

@end

EDIT Okay, the entire first answer has been tossed out. This is, with some warning, still a bit of a shot in a dark, but I think it's going to be closer to helpful. Some of the ideas do carry over though.

  1. You very probably don't need a separate class to act as your ABPeoplePickerNavigationControllerDelegate. In all likelihood, it should be the same class that has your code at the bottom (that calls presentModalViewController:animated:. Since I don't know what controller that was, I'm going to just call it MyViewController for reference. The reason you want that view controller to be the delegate is because, in your delegate methods, you need to be able to dismiss the modal view controller that has the address book.

  2. You definitely don't want the your program's UIApplicationDelegate to be the ABPeoplePickerNavigationControllerDelegate. As you said yourself, peoplePickerDelegate has to be a UIViewController.

So, to MyViewController. First, the interface:

/* MyViewController.h */

@interface MyViewController : UIViewController<ABPeoplePickerNavigationControllerDelegate>
...
@end

Your controller might inherit from a descendant of UIViewController (like a table view controller or something like that) - that shouldn't change, the only thing that should change is adding the ABPeoplePickerNavigationControllerDelegate to the list of implemented protocols.

Now, to implement the functionality:

/* MyViewController.m */

@implementation MyViewController

...
- (void) whateverMethodIsDisplayingTheAddressBook
{
    ABPeoplePickerNavigationController *abPicker = [[ABPeoplePickerNavigationController alloc]init];    
    abPicker.peoplePickerDelegate = self; // This view controller is the delegate
    [self presentModalViewController:abPicker animated:YES];
    [abPicker release];
}

...

- (void)peoplePickerNavigationControllerDidCancel: (ABPeoplePickerNavigationController *)peoplePicker 
{
    [self dismissModalViewControllerAnimated:YES];
}

- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker
      shouldContinueAfterSelectingPerson:(ABRecordRef)person
{   
    [super dismissModalViewControllerAnimated:YES];

    ...get stuff from the Address Book...   

    return NO;
}

- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker
      shouldContinueAfterSelectingPerson:(ABRecordRef)person
                                property:(ABPropertyID)property
                              identifier:(ABMultiValueIdentifier)identifier
{
    return NO;
}

@end
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文