设为首页收藏本站

LUPA开源社区

 找回密码
 注册
文章 帖子 博客
LUPA开源社区 首页 业界资讯 技术文摘 查看内容

Objective-C开发者对Swift亮点的点评

2014-6-16 11:51| 发布者: joejoe0332| 查看: 3563| 评论: 0|原作者: shinancao|来自: 伯乐在线

摘要: 如果这周一你像我一样,正在享受着keynote,很兴奋地要去开始尝试所有新的优美的API。然后当听到讲一门新的语言:Swift时,耳朵都竖起来了!Swift不是对Objective-C的扩展,而是一门全新的语言,这突然震撼到了你。 ...

  如果这周一你像我一样,正在享受着keynote,很兴奋地要去开始尝试所有新的优美的API。然后当听到讲一门新的语言:Swift时,耳朵都竖起来了!Swift不是对Objective-C的扩展,而是一门全新的语言,这突然震撼到了你。也许你很激动?也许你很开心?也许你没什么想法。


  Swift确实已经改变了未来我们开发iOS和Mac上的应用的方式。这篇文章中,我概括了Swift语言的一些亮点,把他们和Objective-C中对应的功能进行了比较。


  请注意这并不是一篇Swift入门指南。苹果已经发布了一本讲解Swift的很棒的书,我强烈建议你去阅读一下。取而代之地是,这是一篇对一些值得关注和使用的特别酷的功能的讨论。


类型

  Swift给出的第一件重大的事情是类型推断。使用类型推断的语言,程序员不需要使用类型信息给变量作注释。编译器可以从给变量赋的值推断出该变量的类型。例如,编译器可以自动把下面这个值设置为String类型:

// automatically inferred
var name1 = "Matt"
// explicit typing (optional in this case)
var name2:String = "Matt"


  连同类型推断一起,Swift还给出了类型安全。在Swift中,编译器(除了少数特殊情况)知道一个对象的完整类型。这使得它能决定怎样来编译代码,因为它有更多的信息随手可用。


  这与Objective-C存在明显的不同,Objective-C本质上是非常动态的。在Objective-C中,编译期间不会真正知道对象的类型。部分原因是你可以在运行时给已有的类添加方法,添加一个全新的类,甚至改变一个实例的类型。


   让我们来更详细地看一下,考虑到下面的Objective-C语句:


Person *matt = [[Person alloc] initWithName:@"Matt Galloway"];
[matt sayHello];


  当编译器看见调用sayHello时,它会检查在头文件中是否声明了这个方法,它会发现类型Person调用了sayHello。如果没有一个Persong对象,就会发生错误,但是这就是编译器所能做的全部了。通常这就足以来捕捉到你引入的bug的第一行了。它会捕捉到输入错误。但是因为动态的特性,编译器不知道sayHello是否将会在运行时改变或者一定会改变。例如,它可以是在协议中的一个可选方法。(还记得这些都可以用respondsToSelector:来检查吗?)。


  因为缺乏强类型,所以当在Objective-C中调用方法时编译器基本上不会太多的事来进行优化。处理动态派发的方法叫做objc_msgSend。我相信你在许多的回溯中已经看见了!在该函数中,会查找选择器的实现,然后再跳转。你不能不承认这增加了开销和复杂性。


  现在看一下在Swift中相同功能的代码实现:


var matt = Person(name:"Matt Galloway")
matt.sayHello()


  在Swift中,编译器知道更多关于类型的信息,这在任何的方法调用中都会起到作用。编译器确切地知道sayHello()在何处被定义。正因如此,通过直接地跳转到实现处而不是必须经过动态派发,编译器可以优化调用的地址。在其他情况下,编译器可以使用虚拟函数表风格派发,这也远低于Objective-C中动态派发的开销。这种类型的派发就是C++中使用的虚函数。


  在Swift中编译器更加的有用。它将帮助阻止不确定的类型导致的bug进入你的代码库。通过智能的优化,还能够使你的代码运行的更加快速。


泛型

  Swift另一个重大的特性是泛型。如果你熟悉C++,你会想起像模板这样的东西。因为Swift是明确类型的,所以你必须在声明一个函数时传递确定的类型。但是有时一些功能对于多个不同的类型是一样的。这种情况的例子就是是经常用到的一对数值构成的一个结构体类型。在Swift中对于整数可以像下面这么实现:

struct IntPair {
    let a: Int!
    let b: Int!

    init(a: Int, b: Int) {
        self.a = a
        self.b = b
    }

    func equal() -> Bool {
        return a == b
    }
}

let intPair = IntPair(a: 5, b: 10)
intPair.a // 5
intPair.b // 10
intPair.equal() // false


  稍微有用。但是现在你想让这个类对于浮点数也适用。你可以定义FloatPair类,但是它会和上面的类非常相似。因此泛型出现了。无需再声明一个全新的类,你只要简单的像下面这样做即可:


struct Pair<T: Equatable> {
    let a: T!
    let b: T!

    init(a: T, b: T) {
        self.a = a
        self.b = b
    }

    func equal() -> Bool {
        return a == b
    }
}

let pair = Pair(a: 5, b: 10)
pair.a // 5
pair.b // 10
pair.equal() // false

let floatPair = Pair(a: 3.14159, b: 2.0)
floatPair.a // 3.14159
floatPair.b // 2.0
floatPair.equal() // false


  相当的有用!为什么你这次会想到这个特性似乎并不清楚,但是相信我:机会是无穷无尽的。你会很快开始明白在自己的代码里何处会用到这些。



酷毙

雷人

鲜花

鸡蛋

漂亮
  • 快毕业了,没工作经验,
    找份工作好难啊?
    赶紧去人才芯片公司磨练吧!!

最新评论

关于LUPA|人才芯片工程|人才招聘|LUPA认证|LUPA教育|LUPA开源社区 ( 浙B2-20090187 浙公网安备 33010602006705号   

返回顶部