iOS程序设计(原书第2版)

更多详情


内容简介: 《iOS程序设计(原书第2版)》全面细致地讲解Cocoa Touch的基础知识,深入解读并剖析在开发iPhone及iPad应用时可能遇到的各种问题,并揭示如何高效地使用Objective-C和Xcode顺利完成iPhone及iPad应用开发之旅。对于首次接触iOS的新手以及期望提升编程技能的iOS开发人员,《iOS程序设计(原书第2版)》都是不二选择。
《iOS程序设计(原书第2版)》不仅讲解涵盖iOS的基础功能,还涵盖iOS的新增功能,包括ARC内存管理、串联图、父视图控制器、页视图控制器、外观代理、CoreImage以及发射层等。

目录: 《iOS程序设计(原书第2版)》
前言
第一部分 语言
第1章 C语言的精髓 2
1.1 编译、语句和注释 3
1.2 变量声明、初始化和数据类型 4
1.3 结构体 6
1.4 指针 7
1.5 数组 9
1.6 运算符 10
1.7 流程控制和条件 12
1.8 函数 15
1.9 指针参数和地址运算符 17
1.10 文件 19
1.11 标准库 21
1.12 更多预处理器指令 22
1.13 数据类型限定符 22
第2章 基于对象的程序设计 24
2.1 对象 24
2.2 消息和方法 25
2.3 类和实例 26
2.4 类方法 27
2.5 实例变量 28
2.6 基于对象的程序设计 29
第3章 Objective-C对象和消息 32
3.1 实例引用就是指针 32
3.2 消息和方法 37
3.3 类型转换和id类型 42
3.4 消息的数据类型 44
3.5 C语言函数 45
3.6 CFTypeRef 46
3.7 块对象 47
第4章 Objective-C类 51
4.1 类和父类 51
4.2 接口和实现 52
4.3 头文件和实现文件 54
4.4 类方法 56
4.5 悄然产生的类对象 56
第5章 Objective-C实例 58
5.1 如何创建实例 58
5.2 多态 62
5.3 self关键字 63
5.4 super关键字 66
5.5 实例变量和存取器 67
5.6 键值编码 68
5.7 属性 69
5.8 如何书写初始化器 71
第二部分 IDE
第6章 Xcode工程的解析 74
6.1 新建工程 74
6.2 工程窗口 76
6.3 工程文件及其依赖 83
6.4 目标 85
6.5 从工程到应用 89
第7章 nib管理 99
7.1 nib编辑界面之旅 99
7.2 nib加载和文件所有者 104
7.3 生成和加载nib文件 105
7.4 插座变量链接 106
7.5 动作链接 113
7.6 对基于nib的实例进行额外初始化 116
第8章 文档 118
8.1 文档窗口 118
8.2 类的文档页 119
8.3 示例代码 122
8.4 其他资源 123
第9章 工程生命周期 126
9.1 选择设备架构 126
9.2 本地化 129
9.3 编辑代码 130
9.4 代码导航 132
9.5 调试 135
9.6 单元测试 141
9.7 静态分析器 141
9.8 清理 142
9.9 在模拟器中运行 142
9.10 在设备上运行 143
9.11 设备管理 146
9.12 版本控制 146
9.13 Instruments 148
9.14 发布 151
9.15 Ad Hoc发布 153
9.16 应用的最后准备 154
9.17 提交到App Store 158
第三部分 Cocoa
第10章 Cocoa类 162
10.1 创建子类 162
10.2 类别 164
10.3 协议 166
10.4 可选方法 170
10.5 一些Foundation类 171
10.6 NSObject探秘 180
第11章 Cocoa事件 183
11.1 产生事件的原因 183
11.2 创建子类 184
11.3 通知 185
11.4 委托 190
11.5 数据源 192
11.6 动作 193
11.7 响应者链 197
11.8 应用程序生命周期事件 199
11.9 被事件淹没 203
第12章 存取器和内存管理 206
12.1 存取器 206
12.2 键值编码 207
12.3 内存管理 210
12.4 属性 234
第13章 数据通信 240
13.1 模型-视图-控制器 240
13.2 实例可见性 242
13.3 通知 244
13.4 键值观察 246
第四部分 视图
第14章 视图 252
14.1 窗口 252
14.2 子视图和父视图 255
14.3 外框 257
14.4 边界和中心 258
14.5 布局 261
14.6 变换 263
14.7 可见性与不透明度 266
第15章 绘图 268
15.1 UIImage 和 UIImageView 268
15.2 图形上下文 271
15.3 UIImage绘图 274
15.4 CGImage绘图 275
15.5 CIFilter 和 CIImage 278
15.6 绘制UIView 280
15.7 图形上下文设置 282
15.8 路径和绘图 283
15.9 剪裁 286
15.10 渐变 287
15.11 颜色和图案 288
15.12 图形上下文变换 290
15.13 阴影 291
15.14 点和像素 292
15.15 内容模式 293
第16章 图层 295
16.1 视图和图层 296
16.2 图层和子图层 297
16.3 在图层中绘制 301
16.4 变换 306
16.5 阴影和边框 311
16.6 图层和键值编码 313
第17章 动画 315
17.1 绘图、动画和线程 315
17.2 UIImageView和UIImage动画 318
17.3 视图动画 320
17.4 隐式图层动画 329
17.5 核心动画 332
17.6 动作 346
17.7 发射层 351
第18章 触摸 356
18.1 触摸事件和视图 356
18.2 接收触摸 358
18.3 限制触摸 359
18.4 解释触摸 360
18.5 手势识别器 364
18.6 触摸传送 373
第五部分 界面
第19章 视图控制器 384
19.1 视图控制器的层次结构 386
19.2 视图控制器和创建视图 389
19.3 旋转 402
19.4 被展示视图控制器 407
19.5 标签栏控制器 415
19.6 导航控制器 418
19.7 页面视图控制器 426
19.8 容器视图控制器 429
19.9 串联图 431
19.10 视图控制器生命周期事件 435
19.11 视图控制器内存管理 437
第20章 滚动视图 441
20.1 创建滚动视图 441
20.2 滚动 444
20.3 缩放 449
20.4 滚动视图委托 454
20.5 滚动视图的触摸 456
20.6 滚动视图的性能 460
第21章 表格视图 461
21.1 表格视图单元格 463
21.2 表格视图数据 476
21.3 表格视图选择 486
21.4 表格视图滚动及布局 491
21.5 表格视图搜索 492
21.6 编辑表格视图 497
21.7 表格视图菜单 506
第22章 弹出窗口及分栏视图 509
22.1 配置和显示弹出窗口 510
22.2 弹出窗口管理 514
22.3 关闭弹出窗口 515
22.4 弹出窗口Segue 518
22.5 自动弹出窗口 519
22.6 分栏视图 521
第23章 文本 527
23.1 UILabel 528
23.2 UITextField 529
23.3 UITextView 539
23.4 Core Text 541
第24章 Web视图 549
24.1 内容加载 550
24.2 与Web视图通信 555
第25章 控件及其他视图 557
25.1 UIActivityIndicatorView 557
25.2 UIProgressView 558
25.3 UIPickerView 560
25.4 UISearchBar 562
25.5 UIControl 565
25.6 栏式控件 580
25.7 外观代理 587
第26章 模态对话框 590
26.1 警告视图 590
26.2 动作表单 593
26.3 对话框替代方案 596
26.4 本地通知 597
第六部分 一些框架
第27章 音频 602
27.1 系统声音 602
27.2 音频会话 603
27.3 音频播放器 608
27.4 远程控制声音 610
27.5 在后台播放声音 612
27.6 关于声音的高级主题 613
第28章 视频 617
28.1 MPMoviePlayerController 617
28.2 MPMoviePlayerViewController 622
28.3 UIVideoEditorController 623
28.4 AV Foundation视频的介绍 625
第29章 音乐库 630
29.1 浏览音乐库 630
29.2 音乐播放器 634
29.3 音乐选择器 638
第30章 照片库和图片拍摄 641
30.1 UIImagePickerController 641
30.2 使用AV Foundation拍摄图片 646
30.3 资源库框架 648
第31章 地址簿 652
31.1 地址簿数据库 652
31.2 地址簿的界面 654
第32章 日历 659
32.1 日历数据库 659
32.2 日历界面 665
第33章 邮件 670
33.1 邮件消息 670
33.2 短信 671
第34章 地图 672
34.1 显示地图 672
34.2 注解 674
34.3 叠加层 680
第35章 传感器 686
35.1 位置 686
35.2 朝向 693
35.3 加速度和姿态 694
第七部分 最后的主题
第36章 持久化存储 706
36.1 沙盒 706
36.2 基本的文件操作 707
36.3 保存和读取文件 708
36.4 用户预置 710
36.5 文件共享 711
36.6 文档类型 712
36.7 处理文档 713
36.8 文档结构 716
36.9 XML 720
36.10 SQLite 726
36.11 图片文件格式 727
第37章 网络基础 729
37.1 HTTP请求 729
37.2 Bonjour 736
37.3 推送通知 737
37.4 除了基础网络之外 738
第38章 线程 739
38.1 主线程 739
38.2 为什么线程难懂 741
38.3 三种使用线程的方式 742
38.4 线程和应用进入后台 753
第39章 撤销 755
39.1 撤销管理器 755
39.2 撤销界面 758
39.3 撤销架构 760
第40章 结语 762

译者序: 正如多年前苹果公司开创了个人PC的时代一样,iPhone开创了移动互联网的时代,苹果公司再次以梦幻的舞步重新回到了舞台的中心。锐意创新和追求完美的苹果公司,在让用户得到美妙而极致体验的同时,也将Objective-C和Cocoa带入到更多程序员的视野中。很少有开发平台能够与iOS相提并论,其一流的系统和框架设计,能够帮助开发者迅速开发出非常优秀的作品。
现在,国内有越来越多的程序员投身到iOS应用和游戏开发的队伍中,无论是新手入门还是需要巩固现有技能,本书都是一本非常好的参考书籍。本书作者本着“授之以鱼不如授之以渔”的态度,深入浅出地介绍了iOS开发中许多必备的基础知识和高级技巧,以理论和实践相结合的方式,并辅以详尽的说明,指导读者掌握iOS的开发技能。作为译者和开发人员,在翻译的过程中,我也学习到了大量的知识。本书并没有为读者准备照搬就可以运行的代码,但是书中所讲的内容都旨在帮助读者理解每一步背后的含义,彻底掌握iOS开发技术。
本书的作者Matt Neuburg有着多年的开发经验,并且是专业技术杂志的特约编辑,有丰富的培训和咨询经验,并在大学中任教。由这样具备实战和教学经验的作者倾力打造的书,自然是一本不可多得的好书。本书涵盖了iOS的方方面面,从Objective-C语言基础和Xcode开发环境介绍,到对Cocoa框架和视图动画的深入剖析,再到线程和网络等高级的主题,本书作者洋洋洒洒、丰富细腻地描绘了iOS这个宏大的主题,可以说真正做到了授之以渔。
本书由陈建设、刘洋、薛晓东、李明合作翻译。感谢机械工业出版社的吴怡老师在整个翻译过程中耐心而细致的工作,及时的沟通协调,我们才得以顺利地完成本书的翻译工作。感谢机械工业出版社的谢晓芳编辑细心严谨的审稿,进一步保证了译文的质量。虽然我们在翻译过程中竭力以信达雅为目标,但是囿于经验和能力,书中的问题和疏漏在所难免,恳请广大读者批评指正。
陈建设。

前言: 苹果公司通过推出第2版iPhone系统做到了一件了不起的事:用已有的Cocoa计算机程序设计框架来为内存和速度都受限的小型触摸屏设备编写应用程序。结果,由此诞生的Cocoa Touch在很多方面比原来的Cocoa还要好。
编程框架都有自己的个性,框架的整体感觉能让人窥见设计者的目标和心态。第一次接触Cocoa Touch时,我对它的评价是:“哇,这真是个聪明人的杰作!”苹果公司虽然故意只在iPhone系统中提供了很少几个内置的界面部件,但它们却比Mac OS X中的对应部件强大而灵活得多,比如UITableView等。更重要的是,苹果公司还为开发者提供了一种非常完美的方法(UIViewController),帮助程序员用基于层次结构的方法对界面的显示、隐藏和替换进行控制。只能在iPhone小屏幕上运行的应用程序因此能够不断展开为多个界面,用户也不至于受到困扰。
更妙的是,苹果公司借此机会把Cocoa打造成全新的Cocoa Touch,并证明了它的优势。Cocoa是一个古老的框架,它的出现甚至早于Mac OS X,在NeXTStep中就存在了。Cocoa日积月累逐渐壮大,为向后兼容性保持了传统的设计。现在,苹果公司紧紧抓住了Cocoa Touch的出现这一机会,抛弃了陈旧的设计。
因此,Cocoa Touch虽然在概念上基于Mac OS X Cocoa,却与后者截然不同,也不由后者定义或限制。Cocoa Touch是一个独立的框架,是一个更精练、更简单、更智能的Cocoa。我能举出无数例子来赞美Cocoa Touch中经过仔细斟酌的系统性设计(以及对奥卡姆剃刀原则的严格遵循)。译注例如Mac OS X的动画层是后来才匆匆加入视图中的,而Cocoa Touch中的所有视图从一开始就有与之对应的动画层。再如Cocoa Touch的内存管理策略更简单而清晰,当nib文件载入时,顶层对象的管理方法更明确。这样的例子数不胜数。
但是,Cocoa Touch归根结底还是来源于Cocoa。它仍然要求开发者具有Objective-C的知识。这不是一门脚本语言,它当然也不是针对非程序员的,诸如HyperCard的HyperTalk或苹果公司的AppleScript这样的语言。它是一门庞大而复杂的语言,学起来并不轻松。
iPhone和iPad的流行以及该平台上大量价格低廉甚至免费的应用程序已经为苹果公司带来了大批新程序员,而且新人还会持续增多。他们在iOS平台上看到了Mac OS X中没有的机会。苹果公司年度的WWDC开发者大会也反映了这种趋势,苹果逐渐将重心从Mac OS X转移到iOS上。
虽然广大程序员对iOS的热忱令人欣喜,但这也造成了大量程序员急功近利,走路都没学会就开始跑。iOS给了程序员强大的主动权,让他们能做想象中的任何事情。但是,iOS同样要求程序员具有必备的基础知识。我经常在网上看到有人提出一些基础问题,他们明显已经沉浸在了开发新应用的乐趣中,却由于不熟悉基础知识而备受打击。
正是这样的现状让我想要写这本书,为读者介绍iOS的基础知识。我热爱Cocoa,早就希望为它写点东西,iOS的流行坚定了我这么做的决心。在写作过程中,本书的主题是“Cocoa Touch编程基础”。在本书中,我将尝试用便于教学的欧几里德式的逻辑顺序提纲挈领地阐述健壮iOS编程所需的基础原则。本书介绍了Objective-C的基础知识(从C语言出发),面向对象编程原则,工具的使用建议,Cocoa对象实例化、引用、相互通信及生命周期管理的完整流程,以及主要界面部件的常见用法与其他常见任务。和我的前一本书一样,我希望你能从本书发现新大陆而兴致勃勃地从头至尾阅读本书,也可将它放到手边以备随时参考。
写本书的目的不是为了替代苹果公司自己的文档和示例工程。苹果公司提供了很棒的在线文档,它们还在不断完善和改进。在准备写作的过程中,我非常依赖于这些资料。同时我还发现它们无法替代有组织且条理性强的教程。由于无法保证读者会按固定的顺序访问在线文档,文档作者也不知道读者在阅读时已经储备了哪些知识。这让在线文档更适合作为参考资料,而不是教程。示例工程中的注释写得再完美,也仍然让人难以理解——它只是为了演示,无法进行教学。
本书则不是这样,本书由章节组成,按页码排序。因而我能够先介绍C语言之后再介绍Objective-C。除了基础知识,本书还会介绍具体的开发经验。贯穿全书你都能看到我提及“初学者常犯的错误”,这其中大部分是我自己犯过的错误。我会尝试说明哪儿有陷阱,否则你可能也会像我一样轻易就掉了进去。在阅读过程中,你能看到我一点点建立起很多完整的示例,或者从稍大的应用程序中拿出一小块进行分析和解释。能教会你编程的并不是一个完整的大项目,而是开发项目的思维过程。我希望你能从本书中获得的正是掌握这种思维过程。
iOS是一个很大的框架,根本无法把所有内容浓缩到一本书中,就连这本大厚书也不行。其实把全部内容压缩到本书中也是不必要且不合适的。本书省略了Cocoa Touch中的若干内容,其中一些内容需要完整的一本书才能清晰描述,而另一些则是在你有了一定基础之后就能轻松地从苹果公司文档中学会的知识。本书只是一个开头,介绍的是基础知识。我希望本书的内容能够为你打下坚实的基础,足以让你应付今后有价值而且有趣的iOS编程中所遇到的各种问题。
本书约定
下面是关于本书印刷字体方面的一些约定:
斜体(Italic)
表示新的术语、URL、电子邮件地址、文件名以及文件扩展名。
等宽字体(Constant width)
用于列出程序清单,也用在正文中表示程序中的变量名、函数名、数据库、数据类型、环境变量、语句和关键字等内容。
等宽粗字(Constant width)
表示需要由用户键入的命令或文本。
等宽斜体字符(Constant width)
表示需要由用户提供的值或由上下文确定的值替换的内容。
注意:这个符号表示提示、建议或一般的注解。
警告:这个符号表示警告。
示例代码的使用
本书的目的是帮助你。一般来说,可以在自己的程序和文档中使用本书的代码。除非复制了相当数量的代码,否则你并不需要联系我们以征得同意。例如,在程序中使用本书中的几段示例代码不必获得许可,但销售或分发包含O扲eilly书籍示例代码的CD-ROM则必须取得我们的授权。引用文书的文字或代码回答问题无需授权,但在自己的产品文档中加入大量本书的示例代码则需要经过我们的许可。
我们欢迎你标明出处,但并不强求。标明出处时通常需要包含书名、作者、出版社以及ISBN,例如,“Programming iOS 5 by Matt Neuburg(O扲eilly). Copyright 2012 Matt Neuburg, 978-1-4493-1934-2”。如果你认为你对代码示例的使用已经超出以上的许可范围,我们很欢迎你通过permissions@oreilly.com联系我们。
Safari联机丛书
Safari联机丛书是应需而变的数字图书馆,它允许你轻松检索超过7500本科技及创新性的参考书籍和视频资料。在此你能快速找到需要的答案。
获得订阅后,你就能访问联机丛书中的全部页面和视频。你能在手机或移动设备上阅读,能在新书上市前就开始阅读,还能访问仍在创作中的图书并向作者提供反馈。你能复制粘贴代码示例,组织收藏夹,下载部分章节,标记关键信息,做笔记,打印页面,还能使用大量其他帮你节省时间的功能。
O扲eilly Media已经将本书加入Safari联机丛书服务中。要访问本书的电子版或来自O扲eilly及其他出版社的相关图书,请到http://my.safaribooksonline.com免费注册。
如何联系我们
请将本书的评论及疑问发给出版社。
美国:O扲eilly Media, Inc.
1005 Gravenstein Highway North
Sebastopol, CA 95472
中国:北京市西城区西直门南大街2号成铭大厦C座807室(100035)
奥莱利技术咨询(北京)有限公司
我们还为本书建立了一个网页,其中包含勘误、示例以及其他信息。其地址是:
http://shop.oreilly.com/product/0636920023562.do
要评论本书或咨询相关技术问题,请发送电子邮件至:
bookquestions@oreilly.com
要获取更多有关我们书籍、课程、会议及新闻的信息,请访问http://www.oreilly.com。
我们的Facebook页面:http://facebook.com/oreilly
在Twitter上关注我们:http://twitter.com/oreillymedia
在YouTube上观看我们的视频:http://www.youtube.com/oreillymedia
第1版致谢
工欲善其事,必先利其器。我在本书的写作过程中利用了很多非常优秀的工具。衷心感谢我的Unicomp Model M键盘(http://pckeyboard.com),没有它我完全无法想象如何才能轻松地敲出这么多文字。很多优秀的软件同样也给了我帮助,包括TextMate(http://macromates.com)以及AsciiDoc(http://www.methods.co.nz/asciidoc)。BBEdit(http://www.barebones.com)的diff显示方式也很有帮助。书中出现的屏幕截图使用Snapz Pro X(http://www.ambrosiasw.com)以及GraphicConverter(http://www.lemkesoft.com)制作。图表使用OmniGraffle(http://www.omnigroup.com)绘制。
O'Reilly优秀的制作工序能在我工作时就把AsciiDoc文本文件转化为PDF格式,让我在模拟的书籍样式中进行检查。要是没有它,以及Early Program程序帮助我在写作过程中定期向读者提供书籍内容更新,我从一开始就不会接受这个工作。我还特别要感谢工具专家Abby Fox一直以来给我提供的帮助。
我采纳了Dave Smith和David Rowland这两位技术审校者提出的很多建议。我还从很多读者中得到了物质和精神上的帮助,他们向我提供勘误,给我鼓励。我尤其有幸与编辑Brian Jepson合作,他热情地指导我使用O扲eilly工具,调整电子版格式,仔细检查图书中的错误,给予了我充分的信任。在我需要与O扲eilly各个部门进行交流时,他还受累充当了中间人的角色。我在O扲eilly写的所有书都离不开Nancy Kotary的帮助,她将我充斥着大量短句的写作风格进行了改善,今后也请多关照。本书中出现的所有错误当然由我来承担责任。
第2版致谢
我无疑要再次感谢我的编辑Brain Jepson,是他促使我写出新版本。Brain,现在可以放下鞭子了!同样感谢O扲eilly团队,他们在各方面给予了我帮助。感谢热忱而忠实的读者给了我许多鼓励和建议。
第2版说明
为了介绍本书第2版和第1版的关系,我首先需要概括一下最近iOS和Xcode的版本历史。
我刚开始写本书第1版时,iPhone的系统版本为3.1.3,iPad为3.2。在写作过程中,iOS 4和iPhone 4发布了,但iOS 4并不能在iPad上运行。后来,苹果公司发布了iOS 4.2,这是第一版同时支持iPhone和iPad的系统。与此同时,Xcode更新到了3.2.5。iOS 4也是第一版支持多任务的系统,开发人员不得不修改应用程序使其适应新世界的规则。
正当我最后一次修订第1版前,Xcode 3.2.6和iOS 4.3发布了,同时还发布了期待已久的Xcode 4的第1个公开版本。Xcode 4可以说是一个全新的集成开发环境,它在菜单、窗口、首选项等各方面都与Xcode 3.2.x不相同。一台Mac中能同时安装Xcode 4与Xcode 3.2.x(最高支持Snow Leopard),它们也能用于开发同一个工程。Xcode 4移除了Xcode 3.2.x中的一些功能,因而一些开发者继续使用旧版本。这样的局面让我很难明确地描述开发过程。对于iOS开发来说,我还是推荐使用Xcode 4,本书第1版就假设读者已经使用了Xcode 4。
这就是2011年5月的情况。当时本书第1版正式出版,介绍了在iOS 4上的编程。
2011年10月,苹果发布了iOS 5。iOS 5中的一些新功能对开发的细枝末节产生了很大的影响,本书因此有必要进行全面的修订。苹果同时还发布了Xcode 4.2。由于这是官方支持iOS 5开发的最早Xcode版本,因此本书假设你正在使用这一版本(或较新版)的Xcode。(通过一系列的技巧,更早的Xcode或许也可以用于iOS 5开发,但这种行为并不支持。)本书第1版包含Xcode 3.2.x中的一些菜单命令和其他界面说明,但这一版删除了这些内容。Xcode 4.2有两个版本,分别在开发机器上运行Snow Leopard(Mac OS X 10.6)和Lion(Mac OS X 10.7)。虽然它们本应完全相同,但各版本都有自己的bug,你可以两种都试试。
正当我在2012年2月完成本书第2版时,Xcode 4.3发布了(仅支持Lion)。它的主要创新在于磁盘文件的组织上:下载的Xcode 4.3不再是安装程序,不会在顶层Developer文件夹中包含众多附属文件及文件夹。它将整个Developer文件夹包含在文件包中(能用Finder的显示包内容命令查看)。当说到Developer文件夹时,你要知道这实际上指的是/Applications/Xcode.app/Content/Developer。除此以外,我还没有找到Xcode 4.2和Xcode 4.3的其他重大区别。在本书中我有时会说“Xcode 4.2”,而这指的是Xcode 4.2或更新的版本。
这一版的主要目的是为iOS 5更新书中的内容。由于读者可能首次接触iOS开发,本书假设读者没有任何在iOS 4或者更老版本的系统上开发的知识。但有的读者可能像我一样从iOS 4过渡到iOS 5,因而本书对iOS 5中的新功能重点进行了介绍。这些内容也能帮助新的iOS开发人员写出可以在iOS 4中运行的应用程序。但是,我这样做的目的并不是为读者提供过时的累赘信息。绝大多数支持iOS 4的设备都已经更新到了iOS 5,我们能比较放心地假设大量用户使用的是iOS 5。因此,不是一定要让应用程序能在旧版本iOS系统中运行的。从教学的角度上看,介绍老旧的方法也没什么好处。对于本书来说,当你确实想了解旧版系统的相关内容时还可以参考前一版。因此,从这一版中删除了iOS 4.2之前的内容。
这里可以举个例子,说明我在本书这一版中对iOS 5中新功能的态度以及教学方法。iOS 5支持的ARC(自动引用计数)彻底改变了Objective-C程序员管理对象内存的方法。甚至可以说,它把Objective-C变成了一门全新的语言。虽然可以选择在iOS编程中不使用ARC,但是由于它对开发有极大的促进作用,我在本书中还是会假设你启用了ARC。第12章介绍了内存管理,这里会像前一版那样向读者描述ARC出现前内存如何管理。但是在其他所有章节中,除非特别说明,所有的示例代码均应该在开启ARC的情况下执行。在Xcode中使用File→New Project(文件→新工程)菜单项建立新的工程,随后选择任何iOS应用程序模板,如果在第2步中选中复选框“Use Automatic Reference Counting”,则会启用ARC。
iOS 5还提供了串联圈这一新功能。串联圈类似于nib文件,允许开发者直接“绘制”界面。二者的主要区别在于一个串联圈文件能够完成多个nib文件的工作。它们在一些地方有所区别,使用方法也不尽相同。但由于它们性质相似,当我在本书中笼统地提到nib文件时,指的是nib或串联圈文件。虽然我会尽量使用完整的名称,但是当我忘了说nib或串联圈时希望各位读者能够谅解我。
最后,我还想对向本书前一版慷慨地提出了批评意见的读者说几句。他们或多或少认为:
1. 这不是一本“食谱书”译注2。
2. 这本书居然用了好几百页来讲基础知识。
3. 书里没有提供让读者能够立即上手的示例应用程序,甚至没有“Hello World”教程。
这些意见都相当中肯,我承认确实如此。但本书的目录以及这个前言一直试图说明:本书根本就不是这些意见中提到的那类书。直截了当地说,本书就是这样的书,而不是其他什么书。这才是我写这本书的最初目的。这些评论希望本书应该是其他什么类型的。但在我看来,那样的书已经够多了,稀缺的正是本书这样的。和我以前进行写作的原因一样,写这本书的原因是我找不到我所需要的书,我不得不自己写一本。我希望本书能对那些确实需要这样一本书的人提供帮助。希望本书是其他类型的读者应该购买别的书,而不是在本书的网站上批评它与想象中相差甚远。我从一开始就没有打算把本书写成那样。
本书会按顺序分重点介绍实际iOS开发所需要的相关知识。这正好与“食谱书”完全相反。本书没有为读者准备简单的教程,只要填入自己的代码就能创建一个应用程序。我认为授之以鱼不如授之以渔。市面上充斥着大量草率地忽略基础知识的书,它们让读者自己学习Objective-C,鼓励大量开发者在尚未打好基础时就尝试进行开发。根据这些开发者提出的问题以及产生的迷惑,我相信他们这时完全不明白自己在做什么。
本书就想纠正这种现象,这要求我介绍大量的基础知识。本书并未强迫你从头至尾阅读所有的基础知识。如果你真的认为已经掌握了所有有关C、Objective-C、Xcode、Cocoa、视图、绘图以及其他东西的知识(你真的确定吗?),尽管跳过开头的几章吧!但请不要对我为需要的人讲解基础知识所费的笔墨而不快。
这就解释了为什么本书没有立即让读者上手编程。本书不是写给那些只能鹦鹉学舌般照着教程写代码的“程序员”的。我的书所讲的是真正的知识,是历经辛苦才能学到的知识。书中所讲的内容能帮你理解进行iOS 5开发的每一步究竟做了什么。这要求投入大量的时间和精力,在开始做任何有实用价值的演示前,我需要介绍大量基础知识。
或许他们误解的部分原因在于没有注意或理解,我之前说的本书会以“便于教学的欧几里德式的逻辑顺序”书写。有些人不知道“欧几里德式”是什么意思。欧几里德写出了第一本世代相传的数学教科书。该书的特色之一是:如果概念B依赖于概念A,就会先介绍概念A。没有什么会推迟,欧几里德绝不会说:“我会在之后解释(证明、讨论)这个东西,现在先姑且相信我说的话。”我试着复制欧几里德的模型。这里举一个例子。每一个iOS应用程序都会用视图控制器,因此,读者在读到第19章描述视图控制器的内容前不会知道真实的iOS应用程序会涉及哪些东西。但要理解视图控制器,需要先理解它控制的究竟是什么;因而第14章以及第四部分剩下的内容都在讨论视图。要掌握视图控制器和视图间的关系,需要先学会Cocoa的架构模式,例如,生命期事件以及响应者链;这就是第11章以及第三部分讨论的内容。视图控制器的视图通常会从nib中载入,这一点在第7章中讨论。以上所有这些都要求首先掌握操作它们时用到的编程语言Objective-C,因此有了第3章。最后,由于Objective-C是C语言的超集,这样就有了第1章。可以看出,要更早地接触到视图控制器几乎是不可能的。我的论证到此结束。
另外,还有读者抱怨本书没有任何可运行的代码。很奇怪,书中到处都有示例代码啊!所有这些代码都能从我的GitHub网站下载(https://github.com/mattneub)。你可以获取这些代码,在Xcode中运行,尽情进行研究。你可以一边阅读一边运行相关的代码,而我也建议你这么做。但是,这些代码并不是为了好玩才写的,它们的作用是帮助你理解书中相应的概念。
在任何情况下,完美的“Hello World”教程一点也不稀奇,网上到处都有,包括苹果公司自己的网站(http://developer.apple.com/library/ios/#documentation/iPhone/Conceptual/iPhone101/Articles/)。根本不需要我来演示写一个简单的iPhone应用程序是多么有趣和轻松。
不过,有人强烈建议我提供“Hello World”程序,否则我的工作就没有做完。既然如此,下面我就给出一个例子,你们可以根据以下步骤一步一步完成:
1. 安装Xcode,启动Xcode。
2. 选择File→New→New Project(文件→新建→新工程)。
3. 在Choose a template对话框中,单击左侧的“iOS”(不是“Mac OS X”)下的“Application”。在对话框右侧,单击“Empty Application”。单击Next按钮。
4. 在“Product Name”中输入Hello。如果“Company Identifier”为空,则输入公司标识符,例如com.yourLastName.yourFirstName。在“Device Family”中选择iPhone。确保3个复选框都没有选中。单击Next按钮。
5. 导航到桌面。不要选中“Create local git repository”复选框。单击Create按钮。
6. 这时工程窗口将会打开。按Command+1组合键。在窗口左半部分单击AppDelegate.m。
7. 现在需要在窗口中部的编辑器中工作。在代码中找到“Override point for customization after application launch.”这一行。将光标移动到该行最右侧并按几次Return键,创建一些空格。在空格中的某处单击,键入下面的代码:
8. 按Command+R组合键,如果有窗口弹出询问是否保存,请接受。
9. 稍等片刻,iOS Simulator程序会自动启动,里面会有一个白色的窗口,其中显示了“Hello, world!”。
恭喜!你完成了第一个“Hello world”程序。这难道不简单吗?难道不无聊吗?难道还有什么重要的意义吗?实际上,你自己还能做得比写刚刚那个程序更好吧?如果你想知道这个问题的答案,想学到足够的知识以便走得更远,继续阅读这本书吧!

媒体评论: “毫无疑问,Neuburg是我最喜爱的编程书籍作者。”
——John Gruber(Daring Fireball)

书摘: 第一部分
语言
苹果提供了强大的iOS开发工具箱,开发者能借此开发出令人满意的程序。这个工具箱就是应用程序编程接口(Application Programming Interface,API)。要利用API,就必须使用它所支持的语言。在大多数情况下,这种语言是基于C语言的Objective-C,也有部分API直接使用C语言。本书这一部分将介绍这些语言的基础知识:
第1章介绍了C语言。一般的开发并不要求你完全掌握C语言的来龙去脉。因此,这一章只介绍了C语言中必须掌握的内容,这些知识是用好Objective-C和基于C语言的API的基础。
第2章讨论了基于对象编程的概念,这奠定了Objective-C的基础。这一章还解释了一些非常重要的术语及其理念,本书中各处都会用到它们。
第3章介绍了Objective-C的基本语法。
第4章继续讲解Objective-C,讨论了Objective-C类的本质,着重讲述了如何编写类代码。
第5章对Objective-C的讲解进行收尾,讨论了实例如何创建和初始化。这一章还介绍了其他一些相关主题,例如,多态、实例变量、存取器、self、super、键值编码和属性等。
我们将会在第三部分回过头进一步学习Objective-C中另一些方面的内容,那些内容与Cocoa框架紧密相关。
第1章
C语言的精髓
要进行iOS开发,你需要与iOS交流,而这是通过iOS API实现的。(API是应用程序编程接口(application programming interface),它规定了你在交流时能说哪些内容。)因此,你需要C程序设计语言的支持,其原因有以下两个:
大多数iOS API使用Objective-C语言,iOS开发过程中主要使用的也是Objective-C语言。Objective-C是C语言的一个超集,即Objective-C建立在C语言之上,C语言中成立的内容在Objective-C中一定也成立。开发者常犯的一个错误就是忘了“Objective-C是C语言的一种扩展”,从而忽略基本的C语言知识。
一些iOS API没有使用Objective-C,而直接使用C语言。即使在Objective-C代码中,你也经常会用到C语言数据结构和函数调用。例如,矩形使用CGRect表示,这是一个C语言结构体(struct)。要用4个数来创建CGRect就需要调用CGRectMake,这是一个C语言函数(function)。iOS API文档中也经常用到C语言,你要有理解它们的能力。
学习C语言最好的方法是阅读Brian W. Kernighan和Dennis M. Ritchie所著的《The C Programming Language》注1(PTR Prentice Hall,1988),一般称为K&R(Ritchie就是C语言的创造者)。这是历史上最好的计算机书籍之一,全书简洁明了、语言精确、内容丰富。K&R对iOS(以及Mac OS X)开发非常重要,我在编程时始终会放一本该书的纸质版在手边以备不时之需,建议你也这么做。另一本有用的手册是Mike Banahan、Declan Brady和Mark Doran所著的《The C Book》,这里有在线版:http://publications.gbdirect.co.uk/c_book/。
幸运的是,并不需要完全掌握C语言的所有知识后才能用好Objective-C。虽然C语言既不庞大也不复杂,但它的一些细节却非常棘手,可用做低级语言的C语言也因此强大而巧妙。我不可能在仅仅一章之内就讲解完C语言的全部知识,也没必要这么做。K&R、《The C Book》或其他地方都有更完整而准确的内容。迟早你会遇到本章中没有(也不该)提到的C语言技术问题,因此我强烈建议你在手边放一本K&R或类似的书以备需要时参考。
我要做的就是在本章中介绍初学者需要重点掌握的C语言内容,在开始使用Objective-C进行iOS开发之前就需要掌握的内容。这也是为什么本章的标题是“C语言的精髓”,它恰好够你舒适而踏实地起步。
对于完全没接触过C语言的读者,我建议在阅读本章的同时也参考阅读K&R(并把本章想象成“C语言初级入门”这种简单的内容)。以下是我对阅读K&R的建议:
快速浏览K&R第1章。
仔细阅读K&R第2章~第4章。
阅读K&R第5章(关于指针和数组)的前3节。由于基本不会用到指针算术,因此该章剩下的内容可以忽略。但是你需要明确理解指针究竟是什么。Objective-C中到处都有对象,而每个对象引用都是指针,代码各处都会看到或用到“*”字符。
阅读K&R第6章(关于结构体)的第1节。初学者不太可能需要定义自己的结构体,但是会经常用到它们(例如,我之前提过的CGRect就是一个结构体),因而需要知道使用结构体的语法。
浏览K&R的附录B中介绍标准库的内容。你可能会用到标准库中的函数,例如,数学运算函数。初学者常常忘记他们还可以利用这个库。
严格说来,K&R介绍的C语言与作为Objective-C基础的C语言稍有不同,这让事情又稍微复杂了一点。K&R出版后出现了各种新的C语言标准(ANSI C、C89、C99),Xcode的编译器也对C语言进行了特有的扩展。Xcode工程在默认情况下使用了GNU99,这是C99的一种扩展(实在愿意的话,你也可以指定使用另一种C语言标准)。但幸运的是,K&R的C语言与Xcode中的C语言非常相似。它们之间最重要的差别只是后者对前者进行了少量改进,使之更方便易用。这些区别都能够轻易发现并记住。因此,K&R仍然是最好且最值得信赖的C语言参考书。
1.1 编译、语句和注释
C语言是一种编译语言。程序用文本的形式进行编写,而运行这个程序则有两个步骤:第一,文本形式的程序编译成机器指令;第二,执行这些机器指令。与任何其他编译语言相同,在编程过程中你可能犯两类错误:
单纯的语法错误(意思是没有正确使用C语言)。这类错误能直接被编译器捕获。这种情况下,程序根本不会开始执行。
如果程序通过了编译器的检查,则它能够开始运行,但你还是有可能犯了其他类型的错误。要找出这样的错误,只能检查程序是否按期待的逻辑执行。
虽然C语言编译器很严格,但你应该感谢它所造成的干预。编译器总是你的好伙伴,接受它,喜欢它。编译器有时会产生一些看似毫不相关或莫名其妙的错误信息,但这肯定是因为你做错了什么而编译器帮你找出了错误。另外,就算对于完全合法的代码,编译器在看到潜在的错误时也可能会产生警告。虽然警告和错误信息不同,但也不应该忽略,它们也是很有帮助的。
我刚刚说过程序运行前需要先经过编译这个步骤。但实际上,编译前还有另一个步骤:预处理。(既可以把它想成编译前一个单独的步骤,也可以想成编译的第一步。)预处理会修改你的程序代码,这会导致最终交给编译器的代码与自己写的代码有一定出入。预处理看似武断而不好用,但它只会根据指令行事,它能让代码更为简洁而清晰。
在Xcode里可以查看预处理后的程序代码(选择Product→Generate Output→Generate Preprocessed File(产品→生成输出→生成预处理后的文件))。当感觉自己错误地使用了预处理器时,可以用这种方法找出它。之后会介绍一些常用的预处理指令。
C语言基于语句,每条语句都以分号结束。(初学者常常犯下忘记分号的错误。)为保持良好的可读性,大多数程序代码都保持一行写一条语句,但这并不是严格的规定。长语句经常会被断开并分割到数行中(遗憾的是,由于Objective-C代码通常会比较冗长,断开一行长代码是很常见的),有时也把两三条很短的语句写到同一行中。但请注意,有些地方是不能换行的,例如,文本字符串不能包含换行符。缩进在语法上没有意义,仅仅是出于习惯才使用缩进(C语言开发者经常以宗教信仰的目光争论应该遵循哪种习惯)。Xcode能够进行自动缩进,你能使用这个功能保持代码的可读性,同时检查是否犯了什么语法错误。
在K&R的C语言中,/* ... */中包含的内容是注释,在注释范围内可以换行(K&R 1.2)。在现代C语言中,注释也可以用双斜杠(//)表示。双斜杠及这一行之后的内容是注释,它们将被忽略掉:
这种注释有时称为C++风格的注释。对于简短的注释来说,它比K&R风格的注释要方便得多。
选择编译器
Xcode中编译器的情况比较复杂。Xcode最早使用了免费的开源编译器GCC(http://gcc.gnu.org)。后来,Xcode逐步引入了另一个免费的开源编译器LLVM(http://llvm.org)。更换编译器可不是件简单的事情,因而苹果公司分阶段进行更换:
混合编译器LLVM-GCC提供了LLVM编译的优点,但代码本身却通过GCC进行解析,从而提供了最大程度的向后兼容性。
纯粹的LLVM编译器(也成为Clang)自己进行代码解析,提供了更智能、信息量更大的错误和警告信息。
在Xcode 3.2.x的发展过程中,最终认为LLVM-GCC是最好的选择。但苹果公司犹豫再三,始终将GCC用做默认编译器。当Xcode 4出现时,LLVM-GCC终于成为默认编译器,此时还可以选择使用GCC。最后,在Xcode 4.2中,LLVM 3.0成为了默认编译器,纯GCC被移除。在Xcode 4.3中,LLVM升级到了3.1版。(选择编译器是一个工程级别的生成选项,请参见第6章。)
在整个C语言中(因而也在整个Objective-C中),需要区分字母大小写。所有的名字都是大小写敏感的。数据类型里没有“Int”,只有小写的“int”。如果声明了一个名为lower的整型变量,然后试图用Lower来描述它,编译器会报错。依照惯例,变量名大多以小写字母开头。
1.2 变量声明、初始化和数据类型
C语言是强类型语言,所有变量都必须先声明并指定数据类型后才能使用。声明的同时也可以为变量初始化一个值。如果变量在声明时没有进行显式初始化,它的值是不确定的(在初始化之前,应该认为它是危险的)。在K&R的C语言中,声明语句必须放在其他任何语句之前。但现代C语言中放宽了这一要求,可以等到需要使用一个变量时再声明它:
C语言内置的基本数据类型都是数字类型:char(1字节)、int(4字节)、float和double(均为浮点数)。这些类型还有一些变种,如short(短整型)、long(长整型)、unsigned short等。iOS对C语言数字类型进行了扩展(通过typedef语句,见K&R 6.7),其中最重要的是NSInteger(及NSUInteger)和CGFloat。除非API有要求,否则平时不需要显式使用这些类型。当需要用到它们时,把NSInteger想成int,把CGFloat想成float就可以了。
当需要显式地把变量的值转换(cast)为另一个类型(也称为类型转换,typecast)时,在变量名前加上一对圆括号,再在圆括号内指定目标类型即可:
在上例中,并非一定要用显式类型转换不可,因为整型数在赋给浮点类型的变量时会隐式转换成浮点数。这只是为了演示类型转换的语法。你在Objective-C中会经常用到类型转换,大多数是为了避免编译器产生警告信息(具体的例子请参见第3章)。
枚举(enum)是另一种初始化数字量的方法(参见K&R 2.3)。它能够将一系列数字按顺序赋给若干个名字,经常用于表示不同的选择。Cocoa API经常使用这一机制。例如,3种可能类型的状态栏动画的定义如下:
上述定义将0赋给UIStatusBarAnimationNone,将1赋给UIStatusBarAnimationFade,将2赋给UIStatusBarAnimationSlide。这样做后,开发者就能直接使用有意义的名字,而无需关心甚至不必知道它们具体是什么数。这个机制很有用,或许你自己也需要定义枚举。
乍看上去,C语言似乎有原生的文本类型(字符串),但这只是错觉。字符串实际上是一个以空字符结尾的字符数组。例如,在C语言中能这样写一个字符串字面量(string literal):
它实际上占用了7个字节的空间:每个字母的ASCII值以及1字节的0用于表示字符串结束。这种不好用的数据结构称为C字符串。如果你的运气够好,进行iOS开发时基本不会或很少会用到它。与字符串打交道时,你一般会用到名为NSString的Objective-C对象类型。NSString与C字符串完全不同,但在Objective-C中书写NSString字面量的方式与C字符串的方式很类似:
请注意开头的“@”符号!这个记号向Objective-C编译器表明建立一个NSString对象。常有人犯下忘记“@”符号的错误,这会导致编译器将它理解为C字符串结果是完全不同的。
……