扩展如何调用ViewController中的函数?扩展内func1访问VC中func2可行吗?
关于Swift扩展调用ViewController函数的问题解答
问题一:扩展(Extension)如何调用ViewController中的函数?
其实这事儿特别直接——扩展本身就是用来给原类补充功能的,只要ViewController里的函数是可访问的,扩展里直接调用就行,完全不用搞什么复杂操作。
举个最接地气的例子:
class ViewController: UIViewController { // 原类里的普通方法,默认访问级别是internal func showGreeting() { print("嗨,我是ViewController里的方法~") } // 静态方法也同理 static func showStaticGreeting() { print("嗨,我是ViewController里的静态方法~") } } // 给ViewController写的扩展 extension ViewController { func callOriginalFunc() { // 实例方法直接用self调用原类的实例方法 self.showGreeting() } static func callOriginalStaticFunc() { // 静态方法用类名调用原类的静态方法 ViewController.showStaticGreeting() } }
这里要注意两个细节:
- 如果扩展和ViewController在同一个.swift文件里,哪怕原类的方法是
private或者fileprivate,扩展也能正常访问; - 如果是不同文件的扩展,那原类的方法至少得是
internal(默认就是这个级别,不用特意声明)或者更开放的public,不然会因为访问权限不够报错。
问题二:定义在扩展中的func1无法访问ViewController类中的func2,是否存在实现该访问的可行方法?
这种情况99%都是访问权限在搞鬼,咱们一步步来解决:
先找问题根源
如果你的代码是下面这样的,那肯定会报错:
// ViewController.swift 文件 class ViewController: UIViewController { // 用了private,限制仅当前类内部能访问 private func func2() { print("我是ViewController里的func2") } } // 另一个文件:ViewController+Extension.swift extension ViewController { func func1() { // 这里直接报错,因为func2是private,跨文件的扩展碰不到它 // self.func2() ❌ } }
可行的解决办法
调整访问级别
把func2的private去掉(默认就是internal),或者如果需要跨模块访问就改成public,这样不同文件的扩展就能正常调用了:class ViewController: UIViewController { // 去掉private,默认internal级别 func func2() { print("我是ViewController里的func2") } } extension ViewController { func func1() { self.func2() ✅ } }把扩展移到同一文件
如果不想修改func2的访问级别(比如必须保持私有),那把扩展和ViewController放在同一个.swift文件里就行——Swift里private的作用域是整个文件,同一文件内的扩展可以访问原类的private方法:// ViewController.swift 文件 class ViewController: UIViewController { private func func2() { print("我是ViewController里的func2") } } // 同一个文件里的扩展 extension ViewController { func func1() { self.func2() ✅ } }不推荐的“野路子”
网上可能有人说用@_spi或者其他私有API手段,但这种方法不稳定,Apple随时可能改掉,而且会导致你的代码在审核或者系统更新时出问题,强烈不建议用。
内容的提问来源于stack exchange,提问作者fred shmed
相关产品推荐
相关产品推荐

