Swift委托模式实例化规则及无需重新实例化视图的实现方法
Swift委托模式的实例化逻辑说明
首先直接回应你最开始的问题:Swift中使用委托模式,只需要在最开始对持有代理的那个对象做一次实例化即可,全程不需要多次创建。
核心疑问解答
- 你代码里
delegate?.drawShapeView(self)中的self,就是当前已经完成全流程初始化的ShapeView实例本身,根本不存在协议自动实例化对象的逻辑。
逻辑很简单:ShapeView是UIView的子类,只有当这个视图已经完成内存分配、属性初始化、被加到视图层级上,系统才会触发它的draw(_:)方法。如果这个视图没有被实例化,连draw(_:)的调用都不会发生,自然也就走不到把self传给代理的这一步。 - 只要代理方法真的被系统触发执行,传进方法的视图参数一定是已经完成实例化、占用内存的有效对象。因为发起代理回调的主体,就是那个已经存在的视图本身——它必须拿着自己的引用,才能去调用代理的方法把自己传过去。
你写的示例代码存在两个核心问题
这段代码本身无法正常运行,也没有正确用到委托的逻辑:
class ShapeViewController: ShapeViewDelegate { drawShapeView(view) }
- 首先是语法错误:Swift不允许直接在类体里写方法调用语句,同时你也没有按照协议要求实现对应的方法签名(协议要求实现的是
func drawShapeView(_ shapeView: ShapeView),不是直接把方法调用写在类里)。 - 其次是类型错配:UIViewController自带的
view属性是控制器的根视图,类型是通用的UIView,并不是你自定义的ShapeView类型,就算语法修正了,也不符合代理方法的参数要求。
委托模式的正确用法,完全不需要重复实例化视图
委托模式的核心是“把部分逻辑的实现权交给别的对象,而本身的对象实例不会重复创建”,完整流程是这样的:
- 全局只需要实例化一次ShapeView,后续不需要重复创建:
// 在控制器里初始化一次ShapeView let shapeView = ShapeView(frame: CGRect(x: 0, y: 0, width: 200, height: 200)) // 把当前控制器设为它的代理,不需要额外新建ShapeView shapeView.delegate = self view.addSubview(shapeView) - 在控制器里正确实现协议方法,接收到的参数就是之前初始化的同一个ShapeView实例,不需要你手动再实例化:
extension ShapeViewController: ShapeViewDelegate { func drawShapeView(_ shapeView: ShapeView) { // 直接用传进来的已有实例绘制即可 let shapePath = UIBezierPath(ovalIn: shapeView.bounds) shapeView.fillColor?.setFill() shapePath.fill() shapeView.strokeColor?.setStroke() shapePath.stroke() } }
认知误区纠正
你之前以为“传入代理方法的视图对象需要自行实例化”,本质是搞反了委托的调用方向:
- 代理方法不是由你(代理方)主动发起调用的,是由持有代理引用的ShapeView主动调用的。ShapeView从创建、显示、到重绘,全程只有同一个实例,它在需要重绘的时候,自己把自己的引用递给代理,让代理帮它完成绘制逻辑。
- 从始至终没有任何环节需要你新建ShapeView对象,自然就实现了你想要的“无需重新实例化视图”的效果。
内容的提问来源于stack exchange,提问作者roadRunner
相关产品推荐
相关产品推荐

