一周前,我开始使用 Swift 学习 OS X 编程。我决定开始创建一个简单的双面板文件管理器来学习语言基础知识和 API。但是现在我发现了一些我无法理解也无法在文档中找到解释的奇怪行为。让他举例说明。
我有一个自定义 ViewController 类 SplitViewController,它表示文件管理器窗口的主要两面板部分。为了让它与底层 View Controller 进行通信,我还使用 FileManagementDelegate 协议(protocol)对其进行了扩展,该协议(protocol)定义了一些有用的方法。
我还有一个 OnePanelViewController 类,用于管理每个文件面板。它还扩展了一个协议(protocol),此时FilePanelController一个,再次用于 Controller 间通信的需要。该协议(protocol)定义为:
protocol FilePanelController {
var delegate: FileManagementDelegate? {get set}
var ID: Int? {get set}
func getSelectedFiles() -> [NSURL]
func getFocus() -> Bool
func gotFocus()
}
在 SplitViewController 类的 viewDidAppear() 方法中,我需要将运行实例设置为两个文件面板的委托(delegate)。我试着这样做:
for controller in self.childViewControllers{
if controller is FilePanelController {
(controller as! FilePanelController).delegate = self
}
}
但这会导致编译时错误:“无法分配给‘FileManagementDelegate’类型的不可变表达式?”
我尝试将代码更改为:
for var controller in self.childViewControllers{...
但是也没用。
同时如果我把它改成:
for controller in self.childViewControllers{
if controller is FilePanelController {
(controller as! OnePanelViewController).delegate = self
}
}
然后一切正常。
要将委托(delegate)属性作为 FilePanelController 协议(protocol)的属性而不是 OnePanelViewController 类的属性进行访问,我必须这样做:
for controller in self.childViewControllers{
if controller is FilePanelController {
var fpController: FilePanelController = (controller as! FilePanelController)
fpController.delegate = self
}
}
这看起来有点尴尬。
我不明白为什么?它是同一类的相同属性。我没有看到这里的问题是什么?
最佳答案
Swift 中的协议(protocol)可以应用于类和结构。编译器不知道你在使用哪个,所以他限制了它。
您可以将协议(protocol)定义为仅适用于类:
protocol FilePanelController: class { ... }
或者使用条件转换:
for controller in self. childViewControllers {
if var filePanelViewController = controller as? FilePanelController {
filetPanelViewController.delegate = self
}
}
当您使用 OnePanelViewController
作为转换类型时,编译器会推断它是类。
关于swift - 类属性分配与协议(protocol)所需的属性分配不同(内部示例)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38897738/