得益于Apple强大的品牌和生态系统,还有互联网的普及,Swift可能是有史以来传播最快的编程语言。不到一个月时间,网上已经出现了大量的资料,教程、问答和源代码。
然而,有关这门语言最基本的一些问题,却没有非常明确的答案。知名的编程教程网站Raywenderlich(由Ray Wenderlich的)发表了Chris Wagner撰写的Swift FAQ,说清楚了很多问题。
总体而言,他们的观点倾向于Swift将成为未来iOS/Mac开发的主流(未来某一天懂Objective-C就像今天你居然会Cobol一样)。但是,正如Google的王越在知乎上谈到的,Swift目前还很不成熟,真正用于生产环境尤其是较大的项目尚需时日。而
是否最后能成大器,取决于Apple的决心和力度,更取决于开发者社区的接受程度。从最初的爆火来看,Swift是大有希望的。毕竟Objective-C(以下简称OC)虽然本身非常优秀,但历史太久,时代的气息太重,各方面已经捉襟见肘了。
基础篇
我是初学者,应该学Swift,还是OC,还是两个都要学?
这取决于你是要在一家iOS开发公司里工作,还是自己干:
- 如果是打工,最好两者都学。因为公司里原有的OC代码你还得搞懂,有些公司不会很快转向Swift。大量的iOS库、教程和示例项目还是用OC写的,你要弄懂就得学OC。
- 如果是自己干,而且只想用Swift,理论上可以只学Swift。但是只要有时间,理解OC仍然是好的。
随着Swift不断成熟,接受度越来越高,这个答案肯定会变化的,最终会有一天,懂OC就像今天你居然会Cobol一样。
我是有多年经验的OC程序员,现在又成小白了?
也是也不是。你仍然有巨大的优势,学习Xcode和Cocoa/Cocoa Touch API所需时间比学Swift要多多了。放心吧,你用Swift会有回家的感觉,应该能很快学会的。
iOS 8和OS X Yosemite应用只能用Swift写吗?
当然不是,Swift和OC之间的互操作是非常流畅的。而且Apple还有大量的OC API和框架没有完全转到Swift。很可能有些公司在完全接受Swift之前还会用OC很多年。
Swift能用在iOS和OS X其他版本上吗?
当然!Xcode 6可以将Swift代码编译为部署在iOS 7以上、OS X 10.9以上的应用。事实上本次WWDC的会议应用就是Swift写的。
不过,现在Apple还不允许beta版本的Xcode 6出来的应用在App Store上架,所以只能等正式版本出来了。
Swift的目的是要取代还是补充OC?
Apple的原话是这么说的:“Objective-C不会消失,Swift和Objective-C都是Cocoa和Cocoa Touch开发的一等公民。”
所以你仍然可以继续使用OC。但是Apple似乎在鼓励大家新应用的开发转用Swift,不过他们也不希望你要重写已有的OC代码。
这纯粹是猜测,但我们估计Apple自己未来的框架和API开发也会转向Swift,某一天OC甚至会被废弃。所以和我们Raywenderlich的小伙伴们一起跳船吧。
Playground是什么
Playground就是一个文件,你写了代码后可以立即看到结果。这对于学习Swift语言、API,开发一些原型代码和算法,都是非常有用的。
不过要注意,你可别当着孩子的面说你要去Playground(英文有游乐场的意思),否则,你说话后直接走到计算机前一座不起,他们会大哭大闹的。
保密协议怎么破?
(按Apple的规矩,开发者在WWDC上看到的非正式版本软件和服务都不能随便公开说的。2008年,由于Apple决定在正式版发布前,iOS SDK仍然应该保密,知名出版社Pragmatic Press的iOS SDK开发图书不得不被迫延期。)
这事儿现在还不太清楚。最近Apple更新了他们的开发者协议:
Further, Apple agrees that You will not be bound by the foregoing confidentiality terms with regard to technical information about pre-release Apple Software and services disclosed by Apple at WWDC (Apple’s Worldwide Developers Conference), except that You may not post screen shots, write public reviews or redistribute any pre-release Apple Software or services. Apple同意,有关WWDC上Apple披露的未发布软件与服务的技术信息,除了张贴屏幕图、撰写公开评论或者再发行软件和服务之外,你将不受上述保密条款的限制。
而且Swift官方电子书和iOS 8 SDK文档都已经公开了,这与以前iOS新版本发布之前同类信息都秘而不宣,已经很不一样了。
但是编写相关教程是不是不违反协议,仍然有待于Apple官方的澄清。
怎么学习Swift
现在已经有很多优秀的Swift学习资源了:
- Apple官方的Swift Programming电子书(有多个中文版:GitHub上协作翻译,另一个GitHub上的不完整版本,CSDN博客,ITEye上的摘录版)
- 这本书也是一个交互教程,可以在Xcode里当成一个Playground边学边实践(Help\Documentation and API Reference\New Features in Xcode 6 Beta\Swift Language\The Swift Programming Language\A Swift Tour\Open Playground)
- WWDC 2014上的Swift视频
- Swift语言速查和快速参考
- CSDN上的Swift资源
- 码农周刊收集的资源列表
- CSDN Code收集的资源列表
- 人人刘兰涛收集的资源列表
- V2EX上的视频列表
这里还会不断更新,请持续关注!
你们未来的书和教程会使用Swift吗?
当然!我们会致力于帮助大家向Swift转移。
新的iOS 8教程会改用Swift编写,但会同时为没有转到Swift的同学提供一些OC示例。
而iOS游戏教程和其他已有教程都会改用Swift。还有视频教程。敬请关注吧。
深入篇
有没有什么Swift能做到,Objective-C却做不到的?反过来呢?
是的。Swift是一种现代的编程语言,增加了许多Objective-C不支持的东西。比较重要的包括名字空间(namspacing),可选类型(optional),元组(tuple),泛型(generics),类型推断(type inference)等等。
Objective-C也有些特性Swift不具备,比如不能传递消息给nil。
细节可以参考Apple的官方文档Using Swift with Cocoa and Objective-C Guide。
有什么API Swift里不能用的吗? 写这篇文章的时候,我还没有发现。但是在OC和Swift API之间通信的时候,还是有一些要注意的地方,比如:
- OC API返回值是id时,Swift接收AnyObject。
- OC API返回值是nil,Swift接收的是值NONE的一个Optional集,这是Swift表示某个变量是nil的方式。因为Swift的变量必须总是保存某个值。
- OC API返回一个集合时,必须转为AnyObject,因为无法推断NSArray或者NSDictionary存的是什么类型。(此处省去了一个例子)
- Swift API返回值是一个元组时,OC将什么都收不到,因为OC不支持元组。除了元组外,泛型、枚举、结构、顶级函数、全局变量、类型别名、Swift式的variadic、嵌套类型、Curry函数等OC里也是不支持的。
Playground里println()的结果输出到哪里去了? 必须打开Assistant Editor查看控制台输出。步骤是:View > Assistant Editor > Show Assistant Editor,或者用快捷Option + Command + Return。
怎么在Playground里看那些很酷的值的图形?
输入如下代码:
for x in 1..10 {
x
}
在边栏上就会看到9 times之类的东西。移动鼠标到这一行,会出现 + 按钮,点击按钮,就能看到图了。
怎样运行REPL?
在终端窗口运行如下命令,使用Xcode的命令行工具:
sudo xcode-select -s /Applications/Xcode6-Beta.app/Contents/Developer/
然后启动Swift REPL:
xcrun swift
要退出时,输入:exit或者:quit,还可以用快捷键 CTRL+D 。
可以用Swift调用我自己的OC代码或者第三方库吗?怎么弄?
当然!在Xcode项目中添加.swift文件时,系统会提示你创建一个桥接头文件。在这个文件中可以导入Swift代码中要用到的OC头。
然后,所有类无需再导入就可以在Swift中调用了。可以像使用系统类那样使用自己的OC代码。
数组只能保存一种类型的对象?那我要保存不同的类型咋办?
Swift里强烈鼓励你只使用强类型数组,也就是只包含一种类型的对象,语法是:
var goodArray: String[] = ["foo", "bar"]
技术上你还是可以创建多类型对象的数组,但是要三思而行。大多数情况下,都不是什么好决策,会使代码混乱。
如果无论如何你还是要一意孤行,可以用AnyObject这样干:
var brokenArray: AnyObject[] = ["foo", 1, 12.23, true]
字典也是这样吗?也是强类型的?
是的。但是同样你还是可以用AnyObject,字典里的值不是同一类型还是很常见的。比如服务器返回的一个JSON响应:
var employee : Dictionary<String, AnyObject> = ["FirstName" : "Larry", "LastName" : "Rodgers", "Salary" : 65_000.00]
不过,还是应该尽量使用默认支持的类,少用字典。
细节篇
Swift里有对应id的东西吗?
有。上面提到,OC API中的id,Swift用AnyObject替代。这个类型可以表示任何类类型的实例。还有一个Any,可以表示任何类型的实例(函数类型除外)。
怎样在Swift中反射?(比如类似if ([obj isKindOfClass:[Foo class]]) { … }这样的)
可以用is关键字检查变量或者常量的类型。编译器很聪明,能告诉你is是否冗余。由于Swift的类型安全性,同一引用不可能之后再改类型。(此处省去一个例子。)
Swift里在enum中怎么存放位移值?(比如MyVal = 1<<5)
很不幸,这方面Swift现在远不如C简洁,不能用enum,得用struct。实例如下:
详情可以参考Nate Cook在StackOverflow上的回答。
Swift里怎么用Grand Central Dispatch?
可以和OC里一样使用C API。
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), {
println("test")
});
处理并发时,也可以使用更高层的NSOperationQueue。
OC中的国际化宏之类咋整?
与OC中的NSLocalizedString宏类似,Swift代码中也要用NSLocalizedString(key:tableName:bundle:value:comment:)方法来处理国际化。 tableName, bundle和value参数都有默认值。示例如下:
NSLocalizedString("Hello", comment: "standard greeting")
未完待续