Iphone 在类别中实现时无法识别协议方法
我有一个视图控制器类,它必须实现几个协议。我有一个习惯,就是把每个协议的方法放在视图控制器类的一个类别中 这一次,我从链接器收到警告,该类没有实现其中一个协议。这些方法在运行时起作用,链接器似乎无法识别类别中的实现 我在一个不同的项目中简化了这个类,在同一个地方得到了相同的错误 类标题:Iphone 在类别中实现时无法识别协议方法,iphone,objective-c,protocols,xcodebuild,categories,Iphone,Objective C,Protocols,Xcodebuild,Categories,我有一个视图控制器类,它必须实现几个协议。我有一个习惯,就是把每个协议的方法放在视图控制器类的一个类别中 这一次,我从链接器收到警告,该类没有实现其中一个协议。这些方法在运行时起作用,链接器似乎无法识别类别中的实现 我在一个不同的项目中简化了这个类,在同一个地方得到了相同的错误 类标题: #import <UIKit/UIKit.h> #import <AddressBook/AddressBook.h> #import <AddressBookUI/Address
#import <UIKit/UIKit.h>
#import <AddressBook/AddressBook.h>
#import <AddressBookUI/AddressBookUI.h>
@interface TopVC : UIViewController
<
UINavigationControllerDelegate,
ABPeoplePickerNavigationControllerDelegate
>
{}
@end
链接器不会抱怨此类别中的此方法。但是,如果我尝试一个类别以相同的方式实现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
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
链接器抱怨:
#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
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
我能看到的唯一区别是UINavigationControllerDelegate
协议方法都是可选的,而ABPeoplePickerNavigationControllerDelegate
都是必需的
然而,即使链接器抱怨,这些方法仍然在运行时被调用。我只是拒绝有一个警告在它的建设。很明显,我在某个地方漏掉了一些东西或犯了一个小错误,但我看不出来 通过声明协议,您打算在主接口上实现,编译器希望在主实现中看到方法(您声明“…[它]是自动生成的,没有任何更改”)。编译器不知道您将在一个类别中实现这些方法。它所知道的是:您“承诺”它们会在那里,但您未能在它预期的地方提供它们。当编译器编译TopVC.m时,它无法知道其他文件将提供其余所需的协议方法。在gcc中,每个.m文件都是独立编译的。您希望将这些内容分成不同的类别是可以的,但是所有这些都需要在TopVC.m中实现 您在
TopVC+ABPeoplePickerNavigationControllerDelegate.h
中对协议方法的重新定义对任何内容都没有影响。@接口中的特定类别标记与@实现中的特定类别标记之间没有关系。@interface中的一个类别定义只是说“这里有一些其他方法可以合法地传递给这个对象,而不生成编译器警告。”这甚至不是创建此类方法的明确承诺。当您表示遵守协议(承诺实现这些方法)时,已经处理了这个问题
@implementation中的类别定义只是说“这个类还有一些其他方法。”类别标记本身只是一个注释。它没有任何关联
您需要将协议实现移动到TopVC.m中,并且没有理由使用
TopVC+.h
文件。如果你想把你的.m分解成单独的@implementation块,那没关系,我认识这样做的人。就我个人而言,我只是使用了#pragma标记来分解文件。哈!我当时脑子一片空白
我忘记将协议实现声明移动到类别的接口,如下所示:
#import "TopVC.h"
@interface TopVC (ABPeoplePickerNavigationControllerDelegateMethods) <ABPeoplePickerNavigationControllerDelegate>
...
@end
#导入“TopVC.h”
@TopVC接口(ABPeoplePickerNavigationControllerDelegateMethods)
...
@结束
这将在没有警告的情况下编译,并按预期工作
我只是因为使用了太多的可选协议而变得懒惰,如果链接器找不到方法实现,它就会忽略这些协议。您好,我做的和您一样,我得到了一个错误:类别正在实现一个方法,该方法也将在它的主类中。
。我做错了什么,或者就是这种方式不再相关了?