转换为ARC - 解析前向引用

时间:2014-06-10 17:13:36

标签: ios objective-c

我继承了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声明)。那里没有快乐。

有关如何解决此问题的任何想法?

谢谢!

2 个答案:

答案 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在帖子中所说。