使用Swift与Cocoa和Objective-C交互-(5)采用 Cocoa 的设计模式

swift 发布于 2017年09月23日
// @interface MyObject : NSObject
// @property (nonatomic, weak) id<NSWindowDelegate> delegate;
// @end
if let fullScreenSize = myDelegate?.window?(myWindow, willUseFullScreenContentSize: mySize) {
    println(NSStringFromSize(fullScreenSize))
}

注意: 在一个纯 Swift 写的 App 中,输入 delegate 作为 Optional 对象 >NSWindowDelegate 的属性,并且为他赋初值 nil

懒加载

信息即将来临,你可以在 Swift 编程语言一书中,读到更多关于懒存储属性的内容。

错误报告

Swift 中的错误报告和 Objective-C 中的一样,并且附加上 Optional 返回值提供的附加特性。在最简单的例子中,你从函数中返回一个 Bool 类型的值来表示是否成功。当你需要报告错误的原因,你可以给函数添加一个 NSErrorPointer 类型的输出参数。这个类型类型几乎等于 Objective-C 的 NSError **类型,并且更加的内存安全和支持 Optional 类型。你可以通过对 Optional 的 NSError 类型添加 & 前缀操作符,就像下面的代码列出的那样:

var writeError : NSError?
let written = myString.writeToFile(path, atomically: false,
    encoding: NSUTF8StringEncoding,
    error: &writeError)
if !written {
    if let error = writeError {
        println("write failure: \(error.localizedDescription)")
    }
}

当你自己实现需要配置 NSErrorPointer 对象的函数,你将 NSErrorPointer 对象的 memory 属性设置为你创建的 NSError 对象。确保调用者首先传递了非 nilNSErrorPointer 对象。

func contentsForType(typeName: String!, error: NSErrorPointer) -> AnyObject! {
    if cannotProduceContentsForType(typeName) {
        if error {
            error.memory = NSError(domain: domain, code: code, userInfo: [:])
        }
        return nil
    }
    // ...
}
Key-Value 检测

信息即将到来。

Target-Action

Target-action 是 Cocoa 一个公用的设计模式,用于当一个指定事件发生时,一个对象向另一个对象发送消息。这个 target-action 模型在 Swift 和 Objective-C 中基本相似。在 Swift 中,你可以使用 Selector 类型来引用 Objective-C 的 selector。关于在 Swift 中使用 target-action 的例子,可以查看 Objective-C Selector 这章。

内省

在 Objective-C 中,你使用 isKindOfClass: 来检测一个对象是否为某些类型,使用 conformsToProtocol: 方法来检测一个对象是否遵守一个特定协议。在 Swift 中,你使用 is 操作符来检测类型,后者使用 as? 操作符来进行向下转型。

你可以通过 is 检测一个实例是否为某些类的子类。如果这个实例是子类的类型,is 操作符会返回 true, 如果不是,会返回 false

if object is UIButton {
    // object is of type UIButton
} else {
    // object is not of type UIButton
}

你还可以试着使用 as? 操作符来向下转型到子类。as? 操作符返回一个 Optional 值,这个值可以使用 if-let 语句绑定到一个常量上面。

if let button = object as? UIButton {
    // object is successfully cast to type UIButton and bound to button
} else {
    // object could not be cast to type UIButton
}

关于更多信息,可以查看 Swift 变成语言中类型转换这章。

检测并转换到某个协议上与检测和转换到某个类上的语法相同。这里是使用 as? 来检测协议兼容性的一个例子:

if let dataSource = object as? UITableViewDataSource {
    // object conforms to UITableViewDataSource and is bound to dataSource
} else {
    // object not conform to UITableViewDataSource
}

注意在这个转换后,dataSource 常量为 UITableViewDataSource 类型,这样你只能调用 UITableViewDataSource 中得方法和属性。如果你要进行其他操作,你必须把他转换成另外的类型。 关于更多的信息,可以查看 Swift 编程语言中协议一章 `


如果你觉得这篇文章有帮助,还可以关注微信公众号 swift-cafe,会有更多我的原创内容分享给你~

本站文章均为原创内容,如需转载请注明出处,谢谢。
关注微信公众号
发现更多精彩
swift-cafe