2016-08-23 46 views
2

我試圖檢測一個方法是否在Swift中使用#function來調用,但返回的結果與#selector的描述不同。這裏有一個工作代碼:Swift中#function和#selector的不同結果

class SampleClass { 

    var latestMethodCall: Selector? 

    @objc func firstMethod() { 
     latestMethodCall = #function 
    } 

    @objc func secondMethod(someParameters: Int, anotherParameter: Int) { 
     latestMethodCall = #function 
    } 

    func isEqualToLatestMethod(anotherMethod anotherMethod: Selector) -> Bool { 
     return latestMethodCall?.description == anotherMethod.description 
    } 
} 


let sampleObject = SampleClass() 

sampleObject.firstMethod() 

let expectedFirstMethod = #selector(SampleClass.firstMethod) 

if sampleObject.isEqualToLatestMethod(anotherMethod: expectedFirstMethod) { 

    print("Working correctly!") 

} else { 

    print("Broken selector...") 

    if let latestMethodCall = sampleObject.latestMethodCall { 
     print("Object's latest method call: \(latestMethodCall.description)") // prints firstMethod() 
     print("Expected method call: \(expectedFirstMethod.description)") // prints firstMethod 
    } 
} 

sampleObject.secondMethod(5, anotherParameter: 7) 

let expectedSecondMethod = #selector(SampleClass.secondMethod(_:anotherParameter:)) 

if sampleObject.isEqualToLatestMethod(anotherMethod: expectedSecondMethod) { 

    print("Working correctly!") 

} else { 

    print("Broken selector...") 

    if let latestMethodCall = sampleObject.latestMethodCall { 
     print("Object's latest method call: \(latestMethodCall.description)") // prints secondMethod(_:anotherParameter:) 
     print("Expected method call: \(expectedSecondMethod.description)") // prints secondMethod:anotherParameter: 
    } 
} 

從上面的示例中,我發現,#function返回斯威夫特-Y說明,而#selector回報ObjC-Y描述。這是預期的嗎?或者我做錯了什麼?

感謝您抽出寶貴時間! :)

回答

1

In Swift < 3.0 Selector類型可以通過String進行初始化。由於這樣做是不安全的(這種方法來自動態Objective-C),Swift 2.2中引入了#selector#selector將不允許您爲不存在的方法定義Selector

現在,讓我們更深入地看看字符串初始化Selector。選擇器的字符串應該具有嚴格的特殊簽名:對於不帶參數的方法func firstMethod()它只是方法名稱,不帶大括號:"firstMethod"。在另一方面,#function關鍵字絕對做不來定義Selector的,它會返回函數標籤用大括號:

@objc func firstMethod() { 
    print(#function) 
} 
//firstMethod() 

如果將定義方法與參數,你會看到,#function現在將返回相同的,但沒有大括號

@objc func firstMethod(param: Int) { 
    print(#function) 
} 
//firstMethod 

因爲Selector,再次,希望其他簽名吧:"firstMethod:"

結論:用於定義Selector使用#selector;在Swift> = 3.0中,你將無法選擇。

+1

啊,我明白了...我忘記補充說我使用了Swift 2.2。根據你的結論,我應該爲'firstMethod'和'#selector(SampleClass.secondMethod(_:anotherParameter :))'''secondMethod'分配帶有'#selector(SampleClass.firstMethod)'的'latestMethodCall',對吧? – edopelawi

+1

只是試着改變'#功能'到'#選擇器',它完美的工作!非常感謝你! – edopelawi