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

Boo*_*oon 9 inheritance objective-c

在子类化类中,我想要子类的父类的子类,因为子类现在具有附加功能.这样做的最佳方法是什么?如果我只是在子类中声明另一个具有相同名称的委托属性,我会收到警告"属性类型'id'与从'ParentClass'继承的类型'id'不兼容

Ror*_*yan 19

鉴于此示例产生警告:

// 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
Run Code Online (Sandbox Code Playgroud)

消除警告的两个解决方案是.

1)在子类中,将协议定义放在类定义之前.这是UITableViewDelegateUITableView.h做:

// Class B
@class ClassB;

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

@interface ClassB : ClassA
@property (nonatomic, weak) id<ClassBDelegete> delegate;
@end
Run Code Online (Sandbox Code Playgroud)

2)在子类中,添加原始协议和新协议:

// Class B
@protocol ClassBDelegete;

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

@protocol ClassBDelegete <ClassADelegete>
- (void)classBDidSomethingElse:(ClassB *)classB;
@end
Run Code Online (Sandbox Code Playgroud)

我假设(1)像苹果那样工作,选项(2)删除警告,但我没有编译和运行任何设置这种方式.


Kur*_*vis 2

NSTableView遵循和的示例NSOutlineView

NSOutlineView是 NSTableView 的子类,并为其dataSource和定义了自己的协议delegate

NSTableView这样声明它的委托:

- (void)setDelegate:(id <NSTableViewDelegate>)delegate;
- (id <NSTableViewDelegate>)delegate;
Run Code Online (Sandbox Code Playgroud)

NSOutlineView

- (void)setDelegate:(id <NSOutlineViewDelegate>)anObject;
- (id <NSOutlineViewDelegate>)delegate;
Run Code Online (Sandbox Code Playgroud)

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

与 NSTable/OutlineView 不同,您可能想让子类的协议继承基类的协议,例如

 @protocol SpecializedProtocol <BaseProtocol>
Run Code Online (Sandbox Code Playgroud)

……这大概要视情况而定。