2015-01-26 41 views
3

給定函數引用,是否有一種方法在Swift中獲取該函數的名稱作爲適合傳遞給NSSelectorFromString的字符串?來自Swift函數的選擇器字符串

我想換NSNotificationCenteraddObserver一個版本,需要一個函數引用,而不是一個選擇字符串:

addObserver(self, function: someCallback, name: "some notification", object: nil) 

addObserver以一個String選擇參數。

+0

http:// stackoverflow。com/a/24049111/2477632 – 2015-01-26 19:27:15

+0

是的,我知道如何在swift中調用addObserver。但我想創建一個新的方法,將函數引用作爲參數並將其轉換爲字符串。 – 2015-01-26 19:51:56

+0

「但addObserver需要一個字符串選擇器參數。」不需要它需要Selector參數。它們不是一回事(即使你有時可以在需要Selector的Swift中使用一個字符串)。 – matt 2015-01-26 20:14:21

回答

0

編輯:我在此離開這裏感興趣,但它太複雜了(被問到如何問,而不是目標)。除了現有的基於塊的方法之外,還有this handy extension to it


我不會這樣做。它太侷限了,因爲它會排除函數文字(匿名函數)。

相反,我會玩這個遊戲:

  • 創建詞典屬性映射[String: Void ->()](字符串函數)
  • 當您註冊一個新的功能,彌補了一個獨特的,隨機密鑰和存儲功能你用這個關鍵詞在你的字典中傳遞。
  • 註冊選擇器observer_dispatcher_<key>(或任何你喜歡的前綴)。
  • 執行resolveInstanceMethod:動態創建任何請求的方法observer_dispatcher_。它們都可以指向同一個IMP,是這樣的:

(假設這是很好的斯威夫特,我還沒有嘗試過):

void _observer_dispatcher(self: AnyObject, _cmd: Selector) { 
    let name = // strip the leading stuff off of _cmd 
    if let f = self.dispatchTable[name] { 
     f() 
    } 
} 

(這仍然是相當草率,我會必須考慮更正確的正確英語詞彙量,但這是我的方向。)

4

您正在重新發明不必要的車輪。 NSNotificationCenter 已經有一個觀察的方法,需要一個函數(什麼Objective-C中所說的「塊」):

addObserverForName:object:queue:usingBlock: 

所以才使用。

+0

謝謝。我忘記了這個版本。查看我的答案,瞭解我如何實施我的原創方法。 – 2015-01-27 06:21:12

0

我還是想找到一個答案,我原來的問題,但基於@馬特的建議,我目前使用這個擴展:

extension NSNotificationCenter { 

    class func addObserver(function: (NSNotification!) ->(), name: String? = nil, object: AnyObject? = nil, queue: NSOperationQueue? = nil) { 
     defaultCenter().addObserverForName(name, object: object, queue: nil, usingBlock: function) 
    } 

} 

因爲它含蓄地使用defaultCenter()並提供默認值objectqueue,其中我幾乎總是通過零的,它允許一個更簡潔的電話:

NSNotificationCenter.addObserver(doSomething, name: "some notification") 

我喜歡它鏈接與實際功能(doSomething),而不是一個字符串表示。這不是一個通用的擴展,但我認爲它覆蓋了我註冊通知的90%的情況。