2
#import "MPOContactAuthorizationManager.h"

@protocol MPOContactAuthorizationManagerDelegate <NSObject>

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

@end

MPOContactAuthorizationManager并且ContactState即使它们在 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;

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

谢谢迈克

4

2 回答 2

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;
于 2013-09-04T00:10:54.407 回答
1

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

@protocol MPOContactAuthorizationManagerDelegate;

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

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

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

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

  • 在你的头文件中声明一个类,它是另一个头文件中定义的类的子类
  • typedef在另一个标题中定义的标题中引用用户定义的类型(例如,通过 a )
  • 在你的头文件中声明一个类符合另一个头文件中声明的协议
  • 在标题中为另一个标题中定义的类声明一个类别
  • 我想我忘了一个,所以把这个空间留给那个。

另请阅读这个启发性的答案

在公共方法参数和属性中需要协议和类名的更常见情况可以使用带有@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
于 2013-09-04T00:14:25.687 回答