unrecognized selector sent to instance 表示執行期嘗試呼叫一個物件不存在的方法。常見於 Target-Action 機制、Delegate、Notification、KVO 等動態派發場景。
| 原因 | 現象 | 修正 |
|---|---|---|
| Selector 拼寫錯誤 | @selector(buttonClick:) 實際方法為 buttonClick(_:) | Swift 4+ 使用 #selector(Class.method) 編譯期檢查 |
| Target 物件已釋放 | 按鈕點擊後 Crash,Target 為弱引用或局部變數 | 確保 Target 持有強引用(如存為類屬性) |
| 方法簽名不符 | func handle() 對應 #selector(handle),但實際需 func handle(_ sender: Any) | Selector 參數數量必須與方法一致 |
| 私有方法未暴露 | private func foo() 無法被 Objective-C 執行期看見 | 加上 @objc 或移除 private |
| 類別未繼承 NSObject | 純 Swift 結構體/類別無法回應 Selector | 類別繼承 NSObject 或標記 @objcMembers |
po $arg1(Target)與 po $arg2(Selector)。po [target respondsToSelector:selector] 驗證方法是否存在。#selector(ViewController.methodName(_:)) 寫法,重構時自動重命名。addAction(UIAction(handler: { _ in ... }), for: .touchUpInside)(iOS 14+),完全避開 Selector。「未識別的選擇器」本質是動態派發與靜態定義不匹配。善用 Swift 編譯期檢查(#selector、@objc)、Zombie 偵測與現代 API,可將此類崩潰降為零。