然后,我尝试在第二个视图中存储对第一个视图的引用,并直接调用函数.这似乎工作:
屏幕1
class Screen1: UIViewController { var myName = "Screen1" override func viewDidLoad() { super.viewDidLoad() } // // checking if the segue to screen 2 is called and then passing a reference // override func prepareForSegue(segue: UIStoryboardSegue!,sender: AnyObject!) { if segue.identifier == "screen2Segue"{ let vc = segue.destinationViewController as Screen2 vc.storedReference = self } } func getName() -> String { return myName } }
屏幕2
class Screen2: UIViewController { var storedReference:Screen1! override func viewDidLoad() { super.viewDidLoad() } func testReference() { // calling a function on the stored reference to screen 1 var str = storedReference.getName() println("Leaving screen 2,going to " + str) } }
我的问题:这段代码怎么了?为什么要使用代理和协议,如果你可以直接传递一个引用呢?
也许相关:视图何时被初始化并被全新的视图实例所替代?我在一个旧的实例上调用’getName()’?
例如,也许您希望将项目存储在某种列表中. List的一些可能的实现包括基于数组的实现和基于节点(linked-list)的实现.如果要声明一个名为List的协议,并且具有实现该协议的类ArrayList和LinkedList,则需要使用列表(作为参数传递给方法,属性等的变量)的任何内容都可以使用List作为变量类型并且能够在不关心列表是ArrayList还是LinkedList的情况下运行.您可以更改使用哪种类型,或者如何实现它们,并且无论使用它们是什么都不重要,因为只有协议中声明的暴露接口才可见.
协议也可以用于模拟像多继承之类的东西,因为类可以从超类继承,也可以实现一个或多个接口. (例如,蝙蝠既是哺乳动物又是翅膀,所以它可以被表示为继承自实施Winged协议的哺乳动物类的蝙蝠类).
委托模式使用协议将一些责任委托给另一个对象,这对于代码分离和可重用性尤其有用.例如,iOS中的UITableViewDelegate协议允许UITableView通过委托另一个对象来处理事件来对单元格选择等进行反应.这几千个应用程序中可能已经被数百万个对象所使用,没有Apple的开发人员实现了UITableView,而UITableViewDelegate已经知道正在实现协议的对象.
通过在视图控制器之间直接传递引用,您强制第二个完全依赖于第一个.如果您希望更改应用程序的流程,以便可以从其他地方访问第二个视图控制器,则将无法重写该视图控制器以使用新的源代码.如果使用协议,则不需要对第二个视图控制器进行任何更改.