如果super
基於NSObject
,你仍然可以以這種方式使用respondsToSelector:
:
if super.respondsToSelector("draggingEnded:") {
super.draggingEnded(sender)
}
更新 - 基於1亞歷克斯評論
而定。一般來說不,你不能在不調用它的情況下使用可選的鏈接來完成此操作。
但是你可以做的是檢查函數是否被調用。但是,僅在特定情況下。必須爲@objc
協議,必須基於NSObject
並且可選函數的返回值不能爲可選。
檢查下面的例子。
@objc protocol Opt {
optional func implemented() -> Void
optional func notImplemented() -> Void
}
class Object: NSObject, Opt {
func implemented() {}
}
let o = Object() as Opt
let implementedCalled = o.implemented?() != nil // == true
let notImplementedCalled = o.notImplemented?() != nil // == false
在此特定情況下,implementedCalled
設爲true
。換句話說,你至少可以檢查方法是否被調用。這是因爲可選的鏈接,並且因爲o.implemented
返回類型是Void
,o.implemented?()
返回Void?
。
你也可以做這樣的事情......
if o.implemented != nil {
// Function is implemented AND implemented WAS CALLED
} else {
// Function is not implemented
}
... ...但不要忘記,如果函數中實現它不檢查,這是 - 如果功能實現,把它和返回.Some(Void)
或.None
,如果它沒有實施。
你的具體情況,你可以這樣做:
override func draggingEnded(sender: NSDraggingInfo?) {
let destination = chainedController as! NSDraggingDestination
if destination.draggingEnded?(sender) == nil {
// .None returned - method not implemented in destination
// draggingEnded is called in super only if it's implemented
// ignore result of type Void?
super.draggingEnded?(sender)
}
}
如果可選功能的返回類型不是Void
,但例如String
,它以同樣的方式表現。
@objc protocol Opt {
optional func name() -> String
}
class Object: NSObject, Opt {
func name() -> String { return "Object" }
}
let o = Object() as Opt
let n: String? = o.name?() // n contains "Object"
如果name
不落實,n
將包含None
。
到目前爲止,一切都很好。我們可以檢查Void
和String
(或任何其他類型)是否被調用。
但是如果返回類型是可選的呢?例如,String?
。
@objc protocol Opt {
optional func name() -> String?
}
class Object: NSObject, Opt {
func name() -> String? { return nil }
}
class Object2: NSObject, Opt {
}
let o = Object() as Opt
let n = o.name?()
let o2 = Object2() as Opt
let n2 = o2.name?()
Object
實現name
,但它返回nil
和Object2
沒有實現name
可言。但n
和n2
都包含nil
。換句話說,如果返回類型是可選的,我們不能檢查函數是否被實現。
正如你所看到的,這很棘手。有時它適合你的需求,有時不適合。如果你確定你的物體是基於NSObject
,堅持.respondsToSelector
是安全的。您可以忽略所有這些情況和案例。
如果你的目標是隻是調用函數,如果它實現了,你不在乎它是否真的實現,如果你對結果沒有興趣,你可以用?
來實現。
是否可以使用swift optionals進行檢查?使用NSObject細節和swift似乎是多餘的。 –
@AlexanderB我只是更新我的答案,更多細節。這不是多餘的,它與Objective-C和Swift的不同性質以及這兩種語言之間的合作。 – robertvojta
嘗試super.draggingEnded?(發件人)是我嘗試的第一件事情,在問題結尾處查看。它不編譯(postfix'?'的操作數應該有可選類型;類型是'(NSDraggingInfo?) - > Void')。嘗試強制讓superDestination =超級,因爲NSDraggingDestination不能編譯。 –