2016-12-26 30 views
3

我有一個抽象類,在我的腦海,我無法實現迅速的幾個特點,所以我用C++來實現我的想法: 如何將複雜的抽象類移植到swift?

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}; 
} 

主要的矛盾是

  1. 純虛擬方法cleanup()要求所有的子類明確實現它(可以用快速實現)
  2. 實例變量_foregroundIndex具有初始值(不能實現使用)
  3. 實例變量_foregroundIndex被限制爲使用)private不能實現

在另一方面,如果使用的class代替,那麼我可以不保證cleanup()方法被覆蓋。

可能會建議將虛方法放在中,並將實例變量放在class中。這可能有用,但不是令人着迷的滿足感。

P.S. Objective-C不是Swift。任何objc_runtime相關的解決方法都不是首選。

+0

斯威夫特不支持抽象類和[計劃已被擊敗](https://github.com/apple/swift-evolution/blob/master/proposals/0026-abstract-classes-and-methods。 MD)。在Swift中沒有完美的解決方法,請參閱[此問題]中的討論(http://stackoverflow.com/questions/24111356/swift-class-method-which-must-be-overridden-by-subclass) –

+0

思考回答,在我看來,你正在將實現細節與API混合在一起。協議只是表示可以使用的公共API來表達一組功能。然而'_foregroundIndex'是一個實現細節。爲什麼協議會關心一個類如何實現協議中描述的功能? – idmean

回答

2

這裏有一個明顯的解決方案,這是我所看到的常常但肯定不能滿足你的是:

func cleanup() { 
    fatalError("You must override cleanup()") 
} 

那麼你可以嘗試使用extension s到擴展默認實現的協議,但擴展不允許存儲的屬性,所以你很可能需要一些外部對象或其他你當然不喜歡的魔法。

正如我在評論中提到的,您可能需要重新考慮您的設計。我不知道你真正想要做的,但也許這樣的事情會制定出適合你:

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 
    } 
} 

這使得我更有意義,因爲這允許任何類型與任何被交換清理處理程序,而無需每次進行分類。