Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 在类别中实现时无法识别协议方法_Iphone_Objective C_Protocols_Xcodebuild_Categories - Fatal编程技术网

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)
...
@结束
这将在没有警告的情况下编译,并按预期工作


我只是因为使用了太多的可选协议而变得懒惰,如果链接器找不到方法实现,它就会忽略这些协议。

您好,我做的和您一样,我得到了一个错误:
类别正在实现一个方法,该方法也将在它的主类中。
。我做错了什么,或者就是这种方式不再相关了?