微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Swift与Objective-C API交互(二

兼容id类型

Swift包含一个AnyObject的协议,与Objective-C中的id类似,可以表示任意类型的对象。AnyObject协议允许你在利用无类型对象的灵活性的同时保持类型安全。
你可以给AnyObject类型的变量赋任意的值:

var myObject: AnyObject = NSData()

可以直接方法AnyObject类型对象的任意属性方法,而不需要进行强制类型转换。

let dateDescription = myObject.description
let timeSinceNow = myObject.timeIntervalSinceNow

由于AnyObject类型的变量的类型需要到运行时才能确定,因此可能会导致不安全的代码。特别是你可以访问一个不存在的属性或者方法,它只是在运行时报错。

myObject.characteratIndex(5)
//crash,myObject doesn't respond to that method

在进行类型转换的时候,不一定转换成功,因此Swift返回的是一个Optional值。你可以检查是否转换成功。

let userDefaults = NSUserDefaults.standardUserDefaults()
let lastRefreshDate: AnyObject? = userDefault.objectForKey("LastRefreshDate")
if let date = lastRefreshDate as? NSDate {
    println("\(date.timeIntervalSinceReferenceDate)")
}

如果你能够确定对象的类型,并且不为nil,可以使用as操作符进行强制转换。

extension UIBezierPath {
    class func bezierPathWithTriangle(length: Float,origin: CGPoint) -> UIBezierPath {
        let squareRoot = Float(sqrt(3))
        let altitude = (squareRoot * length) / 2
        let myPath = UIBezierPath()

        myPath.movetoPoint(orgin)
        myPath.addLinetoPoint(CGPoint(length,origin.x))
        myPath.addLinetoPoint(CGPoint(length / 2,altitude))
        myPath.closePath()

        return myPath
    }
}

可以使用扩展增加属性包括属性或静态属性)。不过这些属性只能是通过计算得来,而不能进行存储。下面给CGRect添加一个area属性

void (^completionBlock)(NSData *,NSError *) = ^(NSData *data,17)">NSError *error) {
    /* ... */
}

在Swift 中对应为:

let completionBlock: (NSData,NSError) -> void = {
    data,error in  Swift的闭包和Objective-C中的Block是兼容的,可以在Swift中给Objective-C的方法传递闭包来代替Block对象。

闭包和Block对象有一点不同,里面的变量是可变的,也就是说与__block修饰的变量行为相同。

对象比较

Swift中有两种对象比较的方式。第一种是相等(==(equality),用来比较两个对象的内容是否相同。第二种是恒等(===(identity),比较两个变量或者常量是否引用同一个对象。

NSObject只能比较是否引用了同一个对象(恒等),如果要比较内容是否相同,应该实现isEqual:方法

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐