Swift实现通用UIViewController获取方法无法访问子类属性怎么办
问题原因
泛型T的具体类型无法通过传入的字符串参数screenID被Swift编译器自动推断,默认将返回值识别为基类UIViewController,因此无法访问子类的自定义属性。
解决方案
方案1:显式声明返回值类型(改动最小)
调用方法时直接指定变量的具体类型,让编译器确认泛型T的实际类型:
// 显式标注变量类型为ListVC let listVcRef: ListVC = getScreen(screenID: "ListVC") listVcRef.lisstArry = [1,2,3,5] self.present(listVcRef, animated: false)
注意:原方法定义的参数名为screenID,调用时不要写错为screenId,否则会报参数不存在的错误。
方案2:优化泛型方法实现(更安全,推荐)
删除硬编码的字符串分支判断,直接将控制器类型作为入参传入,彻底避免字符串写错、分支漏加的问题:
// 修改后的泛型方法 func getScreen<T: UIViewController>(type: T.Type, storyboardName: String, identifier: String) -> T { return getViewController(type, storyboardName, identifier: identifier) as! T } // 调用方式 let listVcRef = getScreen(type: ListVC.self, storyboardName: "ListVC", identifier: "ListVC") listVcRef.lisstArry = [1,2,3,5] self.present(listVcRef, animated: false)
方案3:保留字符串映射逻辑的优化版
如果业务需要必须保留screenID映射逻辑,建议将返回值改为可选类型避免强制转型崩溃:
// 修改后的方法 func getScreen<T: UIViewController>(screenID: String) -> T? { switch screenID { case "ListVC": return getViewController(ListVC.self, "ListVC", identifier: "ListVC") as? T case "ListVC1": return getViewController(ListVC1.self, "ListVC1", identifier: "ListVC1") as? T default: assertionFailure("未匹配到对应screenID的控制器") return nil } } // 调用方式 guard let listVcRef: ListVC = getScreen(screenID: "ListVC") else { return } listVcRef.lisstArry = [1,2,3,5] self.present(listVcRef, animated: false)
内容的提问来源于stack exchange,提问作者Vasu1604
相关产品推荐
相关产品推荐

