(ios) Swift中application作为函数参数无法操作application.delegate?.window

在playground中我做了写了以下的demo

在这里他提示这个UIApplication(是一个class)需要var(class参数应该不需要添加let 、var去控制) 加上之后提示

我然后我怀疑是不是编译器无法判断这个实现了UIApplicationDelegate的delegate属性是class还是struct所以才会出现这个变异错误 。所以我做了以下的强转这下可以通过:

所以我很想知道是什么原因会导致这样。是我姿势不对么。。。问了好多人 叶孤城群里的人冷嘲热讽的。。我试了下 用class去包一个实现某个protocol的struct也不会这样。

谢谢各位了。。

这个问题的话我觉得是编译器提示有问题,产生了一定误导效果,实际上这个问题跟可变参数(参数前加 var )关系不大。

这个问题有两个要点:向下转型和protocol 中 optional 属性。UIApplication 的 delegate 属性是一个实现了 UIApplicationDelegate 协议的类型,UIApplicationDelegate 协议里确实声明了一个 window 属性,但这个属性是 optional 的:

optional public var window: UIWindow? { get set }

也就是说,遵守 UIApplicationDelegate 这个协议的类型,并不一定需要去实现 window 属性的 getter/setter。

一开始你写的application.delegate?.window = UIWindow显然不能通过编译,因为 delegate 虽然必定遵守 UIApplicationDelegate 协议,但它却不一定实现了 window 属性的 set 方法,你又怎么可以直接赋值呢。当你把 application.delegate 向下转型成 AppDelegate 这个类型之后,因为 AppDelegate 内部是明确声明了 windows 属性的(其实可以看作是实现了 UIApplicationDelegate 中 window 属性的 getter/setter),虽然没有显式声明 get 方法,不过编译器已经默认给你加上了,自然也就可以进行赋值了。


看一眼文档吧。。。application.delegate,拿到的是一个遵守protocol的东西,但是这个东西里有什么,并没有告知当前上下文。
但是,appDelegate是遵守了UIApplicationDelegate协议的。所以你可以把拿到的东西转成AppDelegate
appDelegate又申明了一个成员变量uiwindow,相当于实现了delegate中的uiwindow的get/set方法,
所以就可以修改了,好好理解一下这里面的关系层次~

发表评论

电子邮件地址不会被公开。 必填项已用*标注