首页 >iOS开发

[精校版]Using Swift with Cocoa and Objective-C--互通性--采用Cocoa设计模

2014-06-09 17:55 编辑: suiling 分类:iOS开发 来源:CocoaChina
 Swift系列文章由CocoaChina翻译小组翻译自苹果的官方文档:Using Swift with Cocoa and Objective-C--Interoperability--Adopting Cocoa Design Patterns。本篇译者:@JaceFu(git主页),敬请勘误,欢迎在 CocoaChina github主页 查看更多文章!
 
使用Cocoa现有的设计模式,有助于开发者编写一款拥有合理设计思路和良好的可扩展性应用的有效方法之一。大部分这些模式都依赖于在Objective-C中定义的类。由于Swift与Objective-C之间存在互用性,所以你依然可以在Swift代码中使用这些常见的设计模式。很多时候,你可以使用Swift语言的特性来扩展或简化现有的Cocoa设计模式,使这些设计模式更强大、更易于使用。
 
委托
在Swift和Objective-C中,委托通常由一个定义了接口和遵循规范的委托属性的协议表示。与Objective-C相比,当你在Swift中实现委托时,模式不变但实现发生了改变。就像在Objective-C中,在你向委托发送消息之前,你会查看它是否是nil。如果定义的方法是非必须实现的方法,你会查看委托是否对Selector做了响应。在Swift中,这些问题可以得到解决,并能保持类型安全的特性。下面列出的代码可以说明这个过程:
1. 检查myDelegate不为nil。
2. 检查myDelegate实现了window:willUseFullScreenContentSize:方法。
3. 如果myDelegate不为nil并且实现了window:willUseFullScreenContentSize:方法,那么调用该方法,并将该方法的返回值分配给名为fullScreenSize的属性。
4. 打印该方法的返回值。
 
SWIFT
  1. // @inteface MyObject : NSObject 
  2. // @property (nonatomic, weak) id delegate; 
  3. // @end 
  4. if let fullScreenSize = myDelegate?.window?(myWindow, willUseFullScreenContentSize: mySize) { 
  5.     println(NSStringFromSize(fullScreenSize)) 
注意:在一个完全使用Swift编写的app中,在定义delegate属性时,把它作为一个不定值的NSWindowDelegate对象,并将初始值设为nil。
 
延迟初始化
你可以在Lazy Stored Properties中了解到更多关于延迟初始化的信息。
 
错误报告
Swift中的错误报告模式沿用了Objective-C的模式,但Swift中不定值返回值的新特性给我们带来了额外的好处。举个很简单的例子,你用Bool值作为一个函数的返回值,用于标识该函数是否执行成功,当你需要输出错误信息时,你可以在函数中添加一个NSErrorPointer类型的输出参数--NSError。这个类型类似Objective-C中的NSError **,并增加了内存安全性和非强制性的传参。你可以使用&运算符作为前缀引用一个不定值NSError类型作为NSErrorPointer对象传递错误信息。如下面的代码所示:
SWIFT
  1. var writeError : NSError? 
  2. let written = myString.writeToFile(path, atomically: false
  3.     encoding: NSUTF8StringEncoding, 
  4.     error: &writeError) 
  5. if !written { 
  6.     if let error = writeError { 
  7.         println("write failure: \(error.localizedDescription)"
  8.     } 
 
当你实现自己的需要设置一个NSErrorPointer对象的函数时,你需要设置NSErrorPointer对象的memory属性为你创建的NSError对象。检查调用者传递的参数,首先确保它是一个non-nil NSErrorPointer对象。
SWIFT
  1. func contentsForType(typeName: String! error: NSErrorPointer) -> AnyObject! { 
  2.     if cannotProduceContentsForType(typeName) { 
  3.         if error { 
  4.             error.memory = NSError(domain: domain, code: code, userInfo: [:]) 
  5.         } 
  6.         return nil 
  7.     } 
  8.     // ... 
Key-Value Observing
敬请期待。
 
Target-Action
当有特定事件发生,需要一个对象向另一个对象发送消息时,我们通常采用Cocoa的Target-Action设计模式。Swift和Objective-C中的Target-Action模型基本类似。在Swift中,你可以使用Selector类型来参考Objective-C selectors。在Swift代码中使用Target-Action设计模式的示例,可查看Objective-C Selectors
 
内省
在Objective-C中,你可以使用isKindOfClass:方法检查某个对象是否是指定类型,可以使用conformsToProtocol:方法检查某个对象是否遵循特定协议的规范。在Swift中,你可以使用is运算符完成上述的功能,或者也可以使用as?运算符向下匹配指定类型。你可以使用is运算符检查一个实例是否属于指定的子类。如果该实例是指定的子类,那么is运算结果为true,反之为false。
SWIFT
  1. if object is UIButton { 
  2.     // object is of type UIButton 
  3. else { 
  4.     // object is not of type UIButton 
 
你也可以使用as?运算符尝试向下匹配子类型,as?运算符返回一个可使用if-let语句绑定到常量的不定值。
SWIFT
  1. if let button = object as? UIButton { 
  2.     // object is successfully cast to type UIButton and bound to button 
  3. else { 
  4.     // object could not be cast to type UIButton 
请在Type Casting中查看更多信息。
 
检查匹配协议的语法与检查匹配类的语法是一样的,下面是使用as?运算符检查匹配协议的示例:
SWIFT
  1. if let dataSource = object as? UITableViewDataSource { 
  2.     // object conforms to UITableViewDataSource and is bound to dataSource 
  3. else { 
  4.     // object not conform to UITableViewDataSource 
注意,当做完匹配之后,dataSource常量会转换为UITableViewDataSource类型,所以你只能访问和调用UITableViewDataSource协议定义的属性和方法。当你想进行其他操作时,必须将其转换为其他的类型。
 
可以在Protocols查看更多相关信息。
 

 本章由CocoaChina的翻译小组成员 @JaceFu(git主页 翻译,转载请注明出处和译者信息,拒绝商业之用。

搜索CocoaChina微信公众号:CocoaChina
微信扫一扫
订阅每日移动开发及APP推广热点资讯
公众号:
CocoaChina
我要投稿   收藏文章
上一篇:论坛源码推荐(6月9日):用Swift语言开发的RSS阅读器 对图像进行实时模糊处理
下一篇:代码显示iOS 8支持分屏多任务,包含多种选项
我来说两句
发表评论
您还没有登录!请登录注册
所有评论(0

综合评论

相关帖子

sina weixin mail 回到顶部