无法解析协议中的类型

时间:2013-09-04 00:06:41

标签: ios objective-c

#import "MPOContactAuthorizationManager.h"

@protocol MPOContactAuthorizationManagerDelegate <NSObject>

- (void)authorizationManger:(MPOContactAuthorizationManager *)manager
      didUpdateContactState:(ContactsState)contactState;

@end

MPOContactAuthorizationManagerContactState即使在MPOContactAuthorizationManager中声明它们也不会解析为类型:

#import "MPOContactAuthorizationManagerDelegate.h"

typedef enum _contactsState {
    kContactsStateUnknown,
    kContactsStateAllowed,
    kContactsStateDisallowed
} ContactsState;

@interface MPOContactAuthorizationManager : NSObject <UIAlertViewDelegate> {
    ContactsState _contactsAuthorizationState;;
}

@property (strong, nonatomic) NSObject<MPOContactAuthorizationManagerDelegate> *delegate;
@property (nonatomic) ContactsState contactsAuthorizationState;

关于为什么这些没有解决的任何想法?两者都收到错误“预期类型”

由于 麦克

2 个答案:

答案 0 :(得分:3)

你有一个循环依赖。通过删除MPOContactAuthorizationManagerDelegate.h行并添加以下内容来更新#import标题:

@class MPOContactAuthorizationManager;

@protocol行之前。

只需将两者放在一个.h文件中(您仍然需要MPOContactAuthorizationManager的前向声明):

typedef enum _contactsState {
    kContactsStateUnknown,
    kContactsStateAllowed,
    kContactsStateDisallowed
} ContactsState;

@class MPOContactAuthorizationManager;

@protocol MPOContactAuthorizationManagerDelegate <NSObject>

- (void)authorizationManger:(MPOContactAuthorizationManager *)manager
      didUpdateContactState:(ContactsState)contactState;

@end

@interface MPOContactAuthorizationManager : NSObject <UIAlertViewDelegate> {
    ContactsState _contactsAuthorizationState;;
}

@property (strong, nonatomic) NSObject<MPOContactAuthorizationManagerDelegate> *delegate;
@property (nonatomic) ContactsState contactsAuthorizationState;

答案 1 :(得分:1)

使用协议的前向声明替换MPContactAuthorizationManager.h中“MPOContactAuthorizationManagerDelegate.h”的导入:

@protocol MPOContactAuthorizationManagerDelegate;

typedef enum _contactsState {
    kContactsStateUnknown,
    kContactsStateAllowed,
    kContactsStateDisallowed
} ContactsState;

@interface MPOContactAuthorizationManager : NSObject <UIAlertViewDelegate> {
    ContactsState _contactsAuthorizationState;;
}
........

您需要选择此导入方案,因为您在协议标题中引用了用户定义的类型(ContactsState类型) - 因此此标头需要导入管理器的标头。但是,在管理器的标题中,您只将协议称为方法参数的类型,因此您可以合法地在此处声明。

通常,在少数情况下,您只应从另一个标题中导入一个标题:

  • 在标题中声明一个类,该类是另一个标题中定义的类的子类
  • 引用标题中用户定义的类型(例如,通过typedef),在其他标题中定义
  • 将标头中的类声明为符合另一个标头中声明的协议
  • 在标题中为另一个标题中定义的类声明一个类别
  • 我想我忘记了一个,所以为那个节省了这个空间。

另外 - 阅读this enlightening answer

在公共方法参数和属性中需要协议和类名的更常见情况可以使用@class@protocol的前向声明来完成。虽然,如果是我,我会将协议声明保留在与授权管理器相同的标题中 - 这样看起来更方便。请注意,您需要在文件中为此执行前向声明。例如:

typedef enum _contactsState {
    kContactsStateUnknown,
    kContactsStateAllowed,
    kContactsStateDisallowed
} ContactsState;

    //forward-declare the protocol before referencing it in the file
@protocol MPOContactAuthorizationManager;

@interface MPOContactAuthorizationManager : NSObject <UIAlertViewDelegate> {
    ContactsState _contactsAuthorizationState;;
}

@property (strong, nonatomic) NSObject<MPOContactAuthorizationManagerDelegate> *delegate;
@property (nonatomic) ContactsState contactsAuthorizationState;

........

@end

    // Provide the real protocol declaration.
@protocol MPOContactAuthorizationManagerDelegate <NSObject>

- (void)authorizationManger:(MPOContactAuthorizationManager *)manager
      didUpdateContactState:(ContactsState)contactState;

@end