2017-03-26 35 views
0
import Foundation 
class IProtocol { 
    func meth1(arg: Int){} 
} 
class IObserver: IProtocol { 
    private var className: String 
    init(name: String) { 
     className = name 
    } 
    override func meth1(arg: Int) { 
     print(className, ":", arg) 
    } 
} 
class Notifier<T> { 
    private var listOfObservers = NSMutableArray() 
    func addObserver(observer: T) { 
     listOfObservers.add(observer) 
    } 
    func callObservers<ARG, RET>(function: (T)->(ARG)->RET, arg: ARG) { 
     for obj in listOfObservers { 
      let observer = obj as! T 
      _ = function(observer)(arg) 
     } 
    } 
} 
let a = IObserver(name: "First I Observer") 
let b = IObserver(name: "Second I Observer") 
let n = Notifier<IProtocol>() 
n.addObserver(observer: a) 
n.addObserver(observer: b) 
n.callObservers(function: IProtocol.meth1, arg: Int(1)) 

輸出
首先我觀察報:1
其次,我觀察報:1

上面的例子失敗,並沒有建立讓命令失敗,由於signal:Segmentation Fault:11,當我改變IP協議協議。我有不同的協議和不同的觀察者類來確認這些協議。我試圖實現一個Notifier類,它通過從協議和參數傳遞給該方法的方法通知觀察者。
這將是偉大的,如果有人能解釋我做錯了什麼!

我使用斯威夫特3的Xcode 8.2通用Observer模式提供了分段故障

+0

編譯器不應該崩潰。你應該在https://bugs.swift.org上提交一個錯誤。當你將它改爲協議時,我假設你將'{}'從'meth1(arg:)'中移除了? –

+0

是的,Dave,我從IObserver類中刪除了{}以及override關鍵字。 – Arup

回答

0

截至今日,斯威夫特不處理直接引用協議方法

protocol IProtocol { 
    func meth1() 
} 
class IObserver: IProtocol { 
    func meth1() { print("success") } 
} 
let x = IProtocol.meth1 // This causes the compiler crash 
x(IObserver())() 

而來到我的問題的解決方案是通過封閉而不是方法。這是它的外觀:

import Foundation 
protocol IProtocol { 
    func meth1(arg: Int) 
} 
class IObserver: IProtocol { 
    private var className: String 
    init(name: String) { 
     className = name 
    } 
    func meth1(arg: Int) { 
     print(className, ":", arg) 
    } 
} 
class Notifier<T> { 
    private var listOfObservers = NSMutableArray() 
    func addObserver(observer: T) { 
     listOfObservers.add(observer) 
    } 
    func callObservers<ARG>(function: (T, ARG) ->(), arg: ARG) { 
     for obj in listOfObservers { 
      let observer = obj as! T 
      function(observer, arg) 
     } 
    } 
} 
let a = IObserver(name: "First I Observer") 
let b = IObserver(name: "Second I Observer") 
let n = Notifier<IProtocol>() 
n.addObserver(observer: a) 
n.addObserver(observer: b) 
n.callObservers(function: {obs, ar in 
    obs.meth1(arg: ar) 
}, arg: Int(1))