我继承了Objective-C代码,我正在转向ARC。我有一些.h文件声明了一个协议和一个相互引用的接口 - 这是.h文件中的基本模式
@class BasicService;
@class BasicServiceObserver;
@protocol BasicServiceObserver
-(void)UPnPEvent:(BasicService*)sender events:(NSDictionary*)events;
@end
@interface BasicService : NSObject <Events_Observer> {
<<var declarations here>>
}
-(NSUInteger)addObserver:(BasicServiceObserver*)obs;
-(NSUInteger)removeObserver:(BasicServiceObserver*)obs;
-(BOOL)isObserver:(BasicServiceObserver*)obs;
@end
并在.m文件中,BasicServiceObserver引用被标记为转发引用。 .m文件包含上面的.h文件。
//Events_Observer
-(void)someEvent:(NSDictionary*)events{
BasicServiceObserver *obs = nil;
[mMutex lock];
NSEnumerator *listeners = [mObservers objectEnumerator];
while(obs = [listeners nextObject]){
[obs someEvent:self events:events]; // <-- Receiver type 'BasicServiceObserver' for instance message is a forward declaration
}
[mMutex unlock];
}
让我疯了。我试图将协议分成它自己的.h文件并导入它(并删除@class声明)。那里没有快乐。
有关如何解决此问题的任何想法?
谢谢!
答案 0 :(得分:3)
由于BasicServiceObserver
是一个协议,而不是一个类,所以在这种情况下它不应该是前向声明的。将它声明为@class
会误导编译器认为在没有这样的接口时某处会有@interface BasicServiceObserver
。
以下是如何将其转换为编译状态:
@class BasicService;
@protocol BasicServiceObserver
-(void)UPnPEvent:(BasicService*)sender events:(NSDictionary*)events;
@end
@interface BasicService : NSObject <Events_Observer> {
<<var declarations here>>
}
-(NSUInteger)addObserver:(id<BasicServiceObserver>)obs;
-(NSUInteger)removeObserver:(id<BasicServiceObserver>)obs;
-(BOOL)isObserver:(id<BasicServiceObserver>)obs;
@end
同样,在.m文件中
//Events_Observer
-(void)someEvent:(NSDictionary*)events{
id<BasicServiceObserver> obs = nil;
[mMutex lock];
NSEnumerator *listeners = [mObservers objectEnumerator];
while(obs = [listeners nextObject]){
[obs someEvent:self events:events]; // <-- Receiver type 'BasicServiceObserver' for instance message is a forward declaration
}
[mMutex unlock];
}
注意:由于您正在清理文件,请考虑将<<var declarations here>>
部分中的变量移动到.m文件中的类扩展中。这可以帮助您减少.h文件中包含的标头数量,并避免通过标头传播实现的不必要的依赖关系
答案 1 :(得分:0)
正如其他人所指出的,一个类和一个协议并不是一回事。
有时你确实想要定义两者,例如系统UITableView类和UITableViewDelegateProtocol协议。
如果您要同时拥有协议和类,我建议将协议一词添加到协议名称中:
@protocol BasicServiceObserverProtocol
-(void)UPnPEvent:(BasicService*)sender events:(NSDictionary*)events;
@end
但是,最好不要创建BasicServiceObserver类。相反,使所有指向对象的指针都符合该协议
BasicServiceObserverProtocol,正如@dasblinkenlight在帖子中所说。