[英]Convert Unmanaged<AnyObject>! to Bool in Swift
我正在嘗試獲取現有目標 C class 的方法的結果,使用performSelector調用
let result = controlDelegate.performSelector("methodThatReturnsBOOL") as? Bool
我需要將此結果轉換為 Swift 的 Bool 類型。
上面提到的代碼,給出警告
“從'不受管理!' 不相關的類型 'Bool' 總是失敗”
結果始終為“false”,即使該方法返回 YES。
將結果轉換為 Bool 有什么建議嗎?
methodThatReturnsBOOL 的簽名
- (BOOL)methodThatReturnsBOOL
{
return YES;
}
已經有很長一段時間了,因為這仍然沒有答案,所以我正在添加我在學習過程中學到的東西。
要轉換Objective C方法返回的BOOL
值,您只需使用,
if let result = controlDelegate.performSelector("methodThatReturnsBOOL") {
print("true")
} else {
print("false")
}
如果需要,您還可以在此處將值true / false分配給Swift Bool
。
注意 :我嘗試使用takeRetainedValue()
直接將Unmanaged<AnyObject>
為Bool
如SO上的許多答案所示,但在這種情況下似乎不起作用。
這是Swift 3中的解決方案,因為方法有點不同。 此方法還檢查Objective-C對象是否響應選擇器,以避免崩潰。
import ObjectiveC
let selector = NSSelectorFromString("methodThatReturnsBOOL")
guard controlDelegate.responds(to: selector) else {
return
}
if let result = controlDelegate.perform(selector) {
print("true")
}
else {
print("false")
}
你不能在Swift中做你想做的事。 我接受解決方案的問題在於它利用了0x0 恰好是nil
的想法。 Swift和Objective-C規范實際上並未保證這一點。 這同樣適用於布爾值,因為0x0為假,0x1為真只是一個任意的實現決策。 除了在技術上不正確之外,它也只是可怕的代碼才能理解。 在沒有考慮大多數平台上的nil指針(32/64位零)的情況下,所建議的是沒有意義的。
在WWDC '19與工程師談了一段時間后,他建議你實際上可以使用valueFor(forKey:)
,其中鍵是函數名稱/選擇器描述。 這是有效的,因為Obj-C運行時實際上將使用給定的名稱/鍵執行任何函數,以便計算表達式。 這仍然有點hacky,因為它需要了解Objective-C運行時,但是它保證是平台和實現獨立的,因為valueFor(forKey:)
返回Any?
可以毫無困難地投入到Int
或Bool
。 通過使用內置的強制轉換而不是推測0x0或0x1的含義,我們避免了解釋nil指針的整個問題。
例:
@objc func doThing() -> Bool{
return true
}
...
let target = someObjectWithDoThing
let selectorCallResult = target.value(forKey: "doThing")
let intResult = selectorCallResult as? Int //Optional<Int(1)>
let boolResult = selectorCallResult as? Bool //Optional<Bool(true)>
與我在這里的回答相似,這可以通過@convention(c)
來完成:
let selector: Selector = NSSelectorFromString("methodThatReturnsBOOL")
let methodIMP: IMP! = controlDelegate.method(for: selector)
let boolResult: Bool = unsafeBitCast(methodIMP,to:(@convention(c)(Any?,Selector)->Bool).self)(controlDelegate,selector)
這個特殊的語法從Swift 3.1開始可用,也可以在Swift 3中使用一個額外的變量。
更緊湊的轉換為 bool:
let result = controlDelegate.perform(NSSelectorFromString("methodThatReturnsBOOL")) != nil
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.