我脑子里有一个抽象类,我不能在swift中实现它的几个功能,所以我使用C ++来表达我的想法:
template <class T>
class Swapping {
public:
void swap() { _foregroundIndex = backgroundIndex() }
virtual void cleanup() = 0;
T* foreground() { return _buffer[foregroundIndex()]; }
T* background() { return _buffer[backgroundIndex()]; }
void setForeground(T* foreground) { _buffer[foregroundIndex()] = foreground; }
void setBackground(T* background) { _buffer[backgroundIndex()] = background; }
private:
short foregroundIndex() { return _foregroundIndex; }
short backgroundIndex() { return _foregroundIndex ^ 1; }
short _foregroundIndex = 0;
T* _buffer[2] = {NULL, NULL};
}
主要矛盾是
cleanup()
要求所有子类明确地实现它(可以使用protocol
快速实现)_foregroundIndex
具有初始值(不能使用protocol
实现)_foregroundIndex
仅限于private
(无法使用protocol
实现)另一方面,如果我使用class
代替protocol
,那么我无法保证覆盖cleanup()
方法。
有人可能建议将虚拟方法放在protocol
中,将实例变量放在class
中。这可能有效但不是令人满足的。
P.S。 Objective-C不是Swift。任何objc_runtime
相关的解决方法都不是首选。
答案 0 :(得分:2)
有一个明显的解决方案,我经常看到,但肯定不会让你满意的是:
func cleanup() {
fatalError("You must override cleanup()")
}
然后你可以尝试使用extension
来扩展协议的默认实现,但扩展不允许存储属性,所以你很可能需要一些外部对象或其他魔法你当然也不喜欢。
正如我在评论中所述,您可能需要重新考虑您的设计。我不知道你真正打算做什么,但也许这样的事情对你有用:
class Swapper<T> {
private var foregroundIndex = 0
private var backgroundIndex: Int {
return foregroundIndex ^ 1
}
private var buffer: [T?] = [nil, nil]
private let cleanupHandler: () -> ()
init(cleanupHandler: @escaping () -> ()) {
self.cleanupHandler = cleanupHandler
}
func cleanup() {
cleanupHandler()
}
var foreground: T? {
get {
return buffer[foregroundIndex]
}
set {
buffer[foregroundIndex] = newValue
}
}
var background: T? {
get {
return buffer[backgroundIndex]
}
set {
buffer[backgroundIndex] = newValue
}
}
func swap() {
foregroundIndex = backgroundIndex
}
}
这对我来说更有意义,因为这允许任何类型与任何清理处理程序交换,而不必每次都对类进行子类化。