在类别中实现时未识别的协议方法

Tec*_*Zen 3 iphone protocols objective-c xcodebuild categories

我有一个视图控制器类,必须实现几个协议.为了保持整洁,我习惯将每个协议的方法放在视图控制器类的一个类别中.

这次我从链接器收到警告,该类没有实现其中一个协议.这些方法在运行时工作,链接器似乎无法识别类别中的实现.

我在不同的项目中简化了类,我在同一个地方得到了同样的错误.

类标题:

#import <UIKit/UIKit.h>
#import <AddressBook/AddressBook.h>
#import <AddressBookUI/AddressBookUI.h>

@interface TopVC : UIViewController 
<
    UINavigationControllerDelegate,
    ABPeoplePickerNavigationControllerDelegate  
>
{}
@end
Run Code Online (Sandbox Code Playgroud)

TopVC.m(未显示)是自动生成的,没有任何变化.的UINavigationControllerDelegate协议方法此类别中实施:

#import <Foundation/Foundation.h>
#import "TopVC.h"

@interface TopVC (UINavigationControllerDelegate)
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated;
- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated;    
@end

#import "TopVC+UINavigationControllerDelegate.h"

@implementation TopVC (UINavigationControllerDelegate)
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated{
    NSLog(@"navigationController:willShowViewController:animated:");
}

- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated{
    NSLog(@"navigationController:didShowViewController:animated:");
}
@end
Run Code Online (Sandbox Code Playgroud)

链接器不会在此类别中抱怨此方法.但是,如果我尝试以ABPeoplePickerNavigationControllerDelegate相同的方式实现协议的类别,它抱怨:

#import "TopVC.h"

@interface TopVC (ABPeoplePickerNavigationControllerDelegate)

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

- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person;

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

@end

#import "TopVC+ABPeoplePickerNavigationControllerDelegate.h"


@implementation TopVC (ABPeoplePickerNavigationControllerDelegate)

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

}

- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person{
    return YES;
}

- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier{
    return YES;
}
@end
Run Code Online (Sandbox Code Playgroud)

链接器抱怨:

warning: incomplete implementation of class 'TopVC'
warning: method definition for '-peoplePickerNavigationController:shouldContinueAfterSelectingPerson:property:identifier:' not found
warning: method definition for '-peoplePickerNavigationController:shouldContinueAfterSelectingPerson:' not found
warning: method definition for '-peoplePickerNavigationControllerDidCancel:' not found
warning: class 'TopVC' does not fully implement the 'ABPeoplePickerNavigationControllerDelegate' protocol
Run Code Online (Sandbox Code Playgroud)

我能看到的唯一区别是UINavigationControllerDelegate协议方法都是可选的,而这些ABPeoplePickerNavigationControllerDelegate都是必需的.

然而,即使链接器抱怨,这些方法仍然在运行时调用.我只是拒绝在其中添加警告.我显然错过了某些事情或在某处犯了一个小错误但我无法发现它.

Tec*_*Zen 6

哈!我脑子里一片空白.

我忘了将协议实现声明移动到类别的界面,如下所示:

#import "TopVC.h"

@interface TopVC (ABPeoplePickerNavigationControllerDelegateMethods) <ABPeoplePickerNavigationControllerDelegate>
...
@end
Run Code Online (Sandbox Code Playgroud)

这将在没有警告的情况下编译并按预期工作.

我只是在使用如此多的可选协议时变得懒惰,如果找不到方法实现,链接器会忽略它们.