1

考虑以下基类:

@interface ViewBase : UIView
@property (readonly) LayerBase *myLayer;
+ (Class)myLayerClass; // _myLayer = [[[self class] myLayerClass] new];
@end

@interface LayerBase : CALayer
@property AbstractGrid *grid;
@end

class AbstractGrid
{
public:
    int rows, columns;
    virtual someMethod() = 0;
}

我有一个Grid使用不同单元格类型的模板类(AbstractGrid需要,因为无法创建模板 Objective-C 类):

template <class Cell>
class Grid : public AbstractGrid
{
public:
    Cell **cells;
    virtual someMethod() {}
}

现在我想创建一个子类,ViewBase它的类型myLayer也是子类LayerBase(该+myLayerClass方法也被重新定义)并为模型类使用不同的模板参数,例如:

@interface AView : ViewBase
@property (readonly) ALayer *myLayer;
@end

@interface ALayer : LayerBase
@property Grid<GridCell> *grid;
@end

class GridCell
{
public:
    int row, column;
}

该应用程序使用这种方法可以正常工作,但编译器会向我发出有关不兼容属性类型的警告:

属性类型“ALayer *”与继承自“ViewBase”的类型“LayerBase *”不兼容
属性类型“Grid *”与继承自“LayerBase”的类型“AbstractGrid *”不兼容

虽然我可以通过使用 type 声明 layer 属性来消除第一个警告id(这不是最好的解决方案,因为我不能在没有类型转换的情况下使用点语法,而且我可能会犯编译器无法捕捉的错误):

@property (readonly) id myLayer;

我不能对 C++ 类型做同样的事情。grid将属性声明为void *也无济于事。

那么有没有合适的方法来处理这种情况呢?或者我应该简单地使用编译指示使警告静音,因为我知道我在做什么?

请不要建议不要使用 C++ 类,因为它不是一个选项(我正在创建一组跨平台模型类以简化将来的移植)。

4

2 回答 2

1

是的。不要更改返回类型。例如:

@interface LayerBase : CALayer
- (AbstractGrid *)grid;
@end


@interface ALayer : LayerBase

// ALayer's local storage and typed interface:
@property Grid<GridCell>* grid_GridCell; // << use unique selector names

// ALayer's abstract interface/overrides:
- (AbstractGrid *)grid; // << returns self.grid_GridCell

@end
于 2013-09-26T18:00:35.443 回答
0

好吧,我决定删除grid@property(因为在这种情况下我不需要像 KVO 这样的任何属性特性),转而使用旧的 getter/setter,并在子类中简单地转换返回类型。clang 足够聪明,可以允许任意 getter 使用点语法,所以现在我没有收到任何警告。

@interface LayerBase : CALayer {
    AbstractGrid *_grid;
}
- (AbstractGrid *)grid;
- (void)setGrid:(AbstractGrid *)grid;
@end

@implementation LayerBase
- (AbstractGrid *)grid {
    return _grid;
}

- (void)setGrid:(AbstractGrid *)grid {
    _grid = grid;
}
@end

@interface ALayer : LayerBase
- (Grid<GridCell> *)grid;
@end

@implementation ALayer
- (Grid<GridCell> *)grid {
    return (Grid<GridCell> *)[super grid];
}
@end
于 2013-09-26T19:31:13.937 回答