如何在Objective-C中正确子类化委托属性?

时间:2012-03-19 04:27:19

标签: objective-c inheritance

在对类进行子类化时,我还希望子类的父类的子类,因为子类现在具有其他功能。这样做的最佳方法是什么?如果我只是在子类中使用相同的名称声明另一个委托属性,我会收到警告“属性类型'id'与从'ParentClass'继承的类型'id'不兼容

2 个答案:

答案 0 :(得分:18)

给出这个产生警告的例子:

// Class A
@protocol ClassADelegete;

@interface ClassA : NSObject
@property (nonatomic, weak) id<ClassADelegete> delegate;
@end

@protocol ClassADelegete <NSObject>
- (void)classADidSomethingInteresting:(ClassA *)classA;
@end

// Class B
@protocol ClassBDelegete;

@interface ClassB : ClassA
@property (nonatomic, weak) id<ClassBDelegete> delegate; // Warning here
@end

@protocol ClassBDelegete <ClassADelegete>
- (void)classBDidSomethingElse:(ClassB *)classB;
@end

删除警告的两个解决方案是。

1)在子类中,将协议定义放在类定义之前。这是UITableViewDelegate中的UITableView.h

// Class B
@class ClassB;

@protocol ClassBDelegete <ClassADelegete>
- (void)classBDidSomethingElse:(ClassB *)classB;
@end

@interface ClassB : ClassA
@property (nonatomic, weak) id<ClassBDelegete> delegate;
@end

2)在子类中,将原始协议与新协议一起添加:

// Class B
@protocol ClassBDelegete;

@interface ClassB : ClassA
@property (nonatomic, weak) id<ClassADelegete, ClassBDelegete> delegate;
@end

@protocol ClassBDelegete <ClassADelegete>
- (void)classBDidSomethingElse:(ClassB *)classB;
@end

我假设(1)像Apple一样工作,Option(2)删除警告,但我没有编译和运行任何设置。

答案 1 :(得分:1)

请遵循NSTableViewNSOutlineView

的示例

NSOutlineView是NSTableView的子类,并为其dataSourcedelegate定义了自己的协议。

NSTableView以这种方式声明其委托:

- (void)setDelegate:(id <NSTableViewDelegate>)delegate;
- (id <NSTableViewDelegate>)delegate;

NSOutlineView

- (void)setDelegate:(id <NSOutlineViewDelegate>)anObject;
- (id <NSOutlineViewDelegate>)delegate;

显然编译器对于裸方法声明比对属性声明更宽松。

与NSTable / OutlineView不同,您可能希望使子类的协议继承自基类的协议,例如

 @protocol SpecializedProtocol <BaseProtocol>

......这可能取决于具体情况。