如何从子类secondViewController访问父类MainViewController的id属性?
解决方案:在子类中访问父类MainViewController的id属性
你遇到的核心问题是self.parent返回的是UIViewController?类型,而非你的MainViewController,因此无法直接访问id属性,需要先做类型转换。下面提供两种可靠的实现方式:
方法一:安全向下转型访问父类实例
直接对self.parent进行类型校验与转换,确认它是MainViewController实例后再访问id:
class SecondViewController: UIViewController { // 注意:Swift类名建议大写开头 func savedFunc(){ // 安全校验并转型,避免强制解包崩溃 guard let mainVC = self.parent as? MainViewController else { print("当前父控制器不是MainViewController") return } // 正常访问父类的id属性 let prop = viewControllerDictionary(id: mainVC.id, view: mainVC) VCs.shared.storedVc.append(prop) } }
这种方法无需额外维护引用,适合确定父类一定是MainViewController的场景,用guard let做安全校验比强制解包self.parent!更稳妥。
方法二:通过弱引用属性关联父类实例
如果需要多次访问父类实例,或是不想依赖父类层级关系,可以给SecondViewController添加弱引用属性,再在MainViewController中主动赋值:
1. 修改SecondViewController
class SecondViewController: UIViewController { weak var mainViewController: MainViewController? // 弱引用避免循环引用 func savedFunc(){ guard let mainVC = mainViewController else { print("未关联MainViewController实例") return } let prop = viewControllerDictionary(id: mainVC.id, view: mainVC) VCs.shared.storedVc.append(prop) } }
2. 在MainViewController中赋值
当创建或加载SecondViewController时,将自身实例传递给它:
class MainViewController: UIViewController { var id: Int required init?(coder aDecoder: NSCoder) { self.id = 0 super.init(coder: aDecoder) } override func viewDidLoad() { super.viewDidLoad() // 示例:如果是通过Storyboard加载的子类 if let secondVC = children.first(where: { $0 is SecondViewController }) as? SecondViewController { secondVC.mainViewController = self } // 如果是代码创建子类: // let secondVC = SecondViewController() // secondVC.mainViewController = self // addChild(secondVC) // view.addSubview(secondVC.view) // ...后续布局代码 } }
这种方式耦合性更低,明确了依赖关系,适合复杂页面结构的场景。
内容的提问来源于stack exchange,提问作者willd
相关产品推荐
相关产品推荐

