2011-03-05 69 views
10

当我使用LLVM Compiler 2.0时,我似乎遇到了新的错误,这是我之前没有的。重写符合协议的属性

我有一个名为DTGridViewDelegate协议定义为:

@protocol DTGridViewDelegate <UIScrollViewDelegate>

我有一个名为delegate on DTGridView属性(的UIScrollView的一个子类,其本身具有delegate属性)。这被定义为:

@property (nonatomic, assign) IBOutlet id<DTGridViewDelegate> delegate;

现在我得到的消息是:

DTGridView.h:116:63: error: property type 'id<DTGridViewDelegate>' is incompatible with type 'id<UIScrollViewDelegate>' inherited from 'UIScrollView'

因为我曾表示,DTGridViewDelegate符合UIScrollViewDelegate,我认为这将是确定以覆盖这个属性就是这样的,实际上这是第一个编译器提示有问题。

@property (nonatomic, assign) IBOutlet id<DTGridViewDelegate, UIScrollViewDelegate> delegate;

我想知道这是否是一个编译器的问题:

我已经宣布的财产为这种固定的错误?

回答

8

您的设置看起来像UITableView从UIScrollView继承的情况下使用的一样。 UITableViewDelegate协议从UIScrollViewDelegate协议继承。

我成立这编译以下罚款:

// .h 
@protocol ParentClassDelegate 
-(NSString *) aDelegateMethod; 
@end 

@interface ParentClass : NSObject { 
    id delegate; 
} 
@property(nonatomic, assign) IBOutlet id <ParentClassDelegate> delegate; 
@end 

//.m 
@implementation ParentClass 
@synthesize delegate; 

-(id) delegate{ 
    return @"Parent delegate"; 
}//-------------------------------------(id) delegate------------------------------------ 

-(void) setDelegate:(id)someObj{ 
    delegate=someObj; 
}//-------------------------------------(id) setDelegate------------------------------------ 
@end 

//.h 
@protocol ChildClassDelegate <ParentClassDelegate> 
-(NSArray *) anotherDelegateMethod; 
@end 

@interface ChildClass : ParentClass{ 
} 
@property(nonatomic, retain) IBOutlet id <ChildClassDelegate> delegate; 
@end 

//.m 
@implementation ChildClass 
//@synthesize delegate; 

-(id) delegate{ 
    return @"childDelegate"; 
}//-------------------------------------(id) delegate------------------------------------ 

-(void) setDelegate:(id)someObj{ 
    delegate=someObj; 
}//-------------------------------------(id) setDelegate------------------------------------ 

@end 

不知道是什么原因造成您的问题。我要指出,在标题中的UITableViewDelegate协议的样子:

@protocol UITableViewDelegate<NSObject, UIScrollViewDelegate> 

...所以也许编译器会喜欢的东西有时较为明确。

我会建议一个干净的和构建。这解决了很多问题。

+0

我从http://boredzo.org/blog/archives/2009-11-07/warnings开启严格警告,使用Wolf的脚本:http://rentzsch.tumblr.com/post/237349423/hoseyifyxcodewarnings-scpt。这可能解释了为什么你没有看到警告/错误。 – 2011-03-05 15:04:40

+0

虽然你完全正确,但我忘记了UITableViewDelegate,我首先将该代码作为基础!在我看来,第一种方式不应该为此发出警告。另外,我觉得很奇怪,UITableViewDelegate表示它符合NSObject,当它符合UIScrollViewDelegate时,它本身也符合NSObject。 – 2011-03-05 15:13:46

+3

因此,在与@MikeAbdullah进一步讨论后,事实证明我需要在类接口之前放置协议声明。在编译器到达我的属性声明时,@protocol DTGridViewDelegate并不是说它符合。 – 2011-03-06 18:52:38

4

由于没有正式的Objective-C语言规范,因此无法说出编译器是否正常工作。我们可以说的是,苹果的gcc似乎没有上述情况的问题,尽管它在概念上不健全,因为它可以打破Liskov substitution,因为delegatecovariantUIScrollViewDTGridView(尽管协方差同样是一个问题)。如果您通过DTGridView代码期望UIScrollView,然后继续将delegate设置为符合UIScrollViewDelegate但不符合DTGridViewDelegate的对象,会发生什么情况?

+0

这是完全正确的。我觉得奇怪的是,我已经用这两种方式声明了委托,这会在您描述时破坏,但编译器只会警告其中的一个。 – 2011-03-05 15:18:14