Kok*_*oko 15 delegates protocols swift
我试图在Swift中的视图之间传递变量,并遇到了相当抽象的协议和委托概念.
然后我尝试在第二个视图中存储对第一个视图的引用,并直接调用函数.这似乎有效:
屏幕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
}
}
Run Code Online (Sandbox Code Playgroud)
屏幕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)
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题:这段代码出了什么问题?如果您可以直接传递引用,为什么要使用委托和协议?
也许是相关的:视图何时被取消初始化并被全新的视图实例取代?我在旧实例上调用'getName()'吗?
Kam*_*ros 14
协议对于将实现与接口分离很有用,这有助于提高代码的可重用性,可理解性和可测试性.
例如,您可能希望将项目存储在某种类型的列表中.List的一些可能实现包括基于阵列的实现和基于节点的(链接列表)实现.如果你要声明一个被调用的协议List并拥有类ArrayList并且LinkedList实现了该协议,那么任何需要使用列表的内容(作为参数传递给方法,属性等List的变量)都可以用作变量类型,并且能够无需担心列表是一个ArrayList还是一个LinkedList.您可以更改使用的类型或它们的实现方式,对于使用它们的任何内容都无关紧要,因为只有协议中声明的公开接口才可见.
协议也可用于模拟多重继承之类的东西,因为类可以从超类继承,以及实现一个或多个接口.(例如,蝙蝠既是哺乳动物又是翅膀,因此它可以表示为Bat继承自Mammal实现该Winged协议的类的类).
委托模式使用协议将一些职责委托给另一个对象,这对于代码分离和可重用性特别有用.例如,UITableViewDelegateiOS中的协议允许UITableView通过委派另一个对象来处理事件来对单元格选择等内容做出反应.这可能已经数以百万计的成千上万的应用程序的对象,而不会在苹果的开发谁实施UITableView,并UITableViewDelegate已经见过的有关正在实施的协议对象的东西.
通过直接在视图控制器之间传递引用,您强制第二个完全依赖于第一个.如果您希望更改应用程序的流程以便可以从其他位置访问第二个视图控制器,则会强制您重写该视图控制器以使用新的原点.如果使用协议,则不必更改第二个视图控制器.
小智 7
不再暴露任何设计是一个基本的设计原则.通过传递参考,你将暴露整个对象.这意味着其他人可以调用其任何功能并访问其任何属性.并改变它们.这不好.除了让其他人以可能没有预期的方式使用对象之外,如果你试图在将来改变对象并发现它打破了使用你不想要的东西的其他人,你也会遇到问题.因此,不要暴露任何你不需要的东西总是一个好主意.这是代表和协议的目的.它使对象完全控制所暴露的内容.更安全.更好的设计.
我认为您没有完全理解什么是协议。
\n\n我总是说协议就像合同。
\n实现某种协议的委托对象承诺它可以做委托者不能做的事情。
在现实世界中,我家的管道有问题。
\n我(委托人)打电话给水管工(委托人)来修复它。水管工承诺(根据合同)能够双人使用。承诺就是协议。我不在乎他怎么做,只要他做了就行。
But these contracts are not only useful for delegation.
\nI am just writing a food ordering app. As it has a menu it need item to display in it.
\nI could go with basic inheritance and write a class MenuItem, that all sub classes must inherit from.
\nOr I write an protocol to express: \xc2\xabNo matter what object you are, as long as you fulfill this contract we have a deal\xc2\xbb. this allows me to create many different classes or annotate existing classes in categories, although I don\'t have the tool of multiple inheritance.
Actually I do both: I write a protocol MenuItem and a class MenuItem that conforms to the protocol. Now I can use simple inheritance or use classes that do not inherit from the class MenuItem.
Code in Objective-C (sorry: I am still transitioning to Swift)
\n\n@protocol MenuItem <NSObject>\n\n-(NSString *)name;\n-(double) price;\n-(UIColor *)itemColor;\n\n@end\n\n\n@interface MenuItem : NSObject <MenuItem>\n@property (nonatomic, copy) NSString *name;\n@property (nonatomic, assign) double price;\n@property (nonatomic, strong) UIColor *itemColor;\n\n@end\nRun Code Online (Sandbox Code Playgroud)\n\n#import "MenuItem.h"\n\n@implementation MenuItem\n\n-(id)initWithCoder:(NSCoder *)decoder\n{\n self = [super init];\n if (self) {\n self.name = [decoder decodeObjectForKey:@"name"];\n self.price = [decoder decodeDoubleForKey:@"price"];\n self.itemColor = [decoder decodeObjectForKey:@"itemColor"];\n }\n return self;\n}\n\n-(void)encodeWithCoder:(NSCoder *)encoder\n{\n [encoder encodeDouble:self.price forKey:@"price"];\n [encoder encodeObject:self.name forKey:@"name"];\n [encoder encodeObject:self.itemColor forKey:@"itemColor"];\n}\n\n\n@end\nRun Code Online (Sandbox Code Playgroud)\n\nApple uses the same Architecture for NSObject: there is a protocol and a class NSObject. This allows classes, that aren\'t intact inheriting from the class NSObject to act ash an NSObject. One famous example:NSProxy.
in your case Screen1 promises to be able to understand messages that are send by the detail view controller Screen2. These allows decoupling: any object that does understand Screen1\'s protocol can be used. Also it helps to maintain a sane object tree, as we don\'t have to have circular imports. But in general you have to keep in mind that the delegator (Screen2) must keep a weak reference to it\'s delegate, otherwise we have a retain circle.
\n\nOf course an important example it UITableView:
\nThe table view object knows everything about rendering it\'s cells, handling scrolling and so one. But the engineer who wrote it couldn\'t now how you want your table view look like. That\'s why he introduced a delegate to give you the chance to create the right cell. As he couldn\'t also know what your data looks like, he also introduced the datasource\xc2\xa0- that works exactly like a delegate: you will be asked to provide all information about your data, that are needed.
| 归档时间: |
|
| 查看次数: |
4950 次 |
| 最近记录: |