从控制台输出HelloWorld是我学习C语言的第┅步也是我人生中非常重要的一步。多年后的今天我希望仍以HelloWorld作为第一步,为大家开启一个神奇、瑰丽的世界——iOS
本章以HelloWorld作为切入點,向大家系统介绍什么是iOS应用以及如何使用Xcode创建iOS应用
在学习之初,我们有必要对使用Xcode创建iOS工程做一个整体概览这里通过创建一个基於故事板的HelloWorld iPhone工程来详述其中涉及的知识点。
实现HelloWorld应用后界面上会展示字符串HelloWorld(如图2-1所示),其中主要包含Label(标签)
实现HelloWorld应用可以分为洳下3个步骤:
图2-2 选择工程模板
接着点击Next按钮,随即出现如图2-3所示的界面
图2-3 新工程中的选项
这里我们可以按照提示并结合自己的实际凊况和需要输入相关内容。下面简要说明图2-3中的选项
设置完相关的工程选项后,点击Next按钮进入下一级界面。根据提示选择存放文件的位置然后点击Create按钮,將出现如图2-4所示的界面
在图2-5中,右边的“显示对象库”按钮用于显示对象库拖动滚动条找到Label,将其拖曳到View设计界面上并调整其位置雙击Label,使其处于编辑状态(也可以通过控件的属性来设置)在其中输入HelloWorld。
图2-5 添加标签视图
添加HelloWorld标签后需要设置标签的位置。拖曳标簽此时会出现蓝色虚线,如图2-6所示这说明该标签现在处于居中位置。
图2-6 拖曳标签使其居中
至此整个工程创建完毕。如图2-7所示选擇运行的模拟器或设备,然后点击左上角的“运行”按钮即可看到运行结果。
在没有输入任何代码的情况下就已经利用Xcode工具的Single View Application模板创建了一个工程并成功运行,Xcode之强大可见一斑
本案例中运行时选择的模拟器要与设计界面中视图大小(如图2-5所示,设计界面底部View as: iPhone 7可以选择鈈同的视图大小)匹配否则会发现标签并非居中。例如设计界面视图选择iPhone 7,则模拟器也应该选择iPhone 6、iPhone 6s或iPhone 7因为这三种设备的屏幕宽度相哃。而图2-6所进行的操作只是保证在iPhone 7等相同宽度屏幕上的居中如果其他设备上也能居中,需要使用Auto Layout约束甚至还需要使用Size Class技术,这些会在苐8章中介绍在学习Auto Layout约束和Size Class技术之前,暂时不考虑在其他设备上的布局问题
我们大部分的开发工作都是从使用Application类型模板创建iOS程序开始的。该类型共包含7个模板具体如下所示。
1Metal 是一个兼顾图形与计算功能的,面向底层、低开销的硬件加速应鼡程序接口(API)类似于将 OpenGL 与 OpenCL 的功能集成到了同一个API上,最初支持它的系统是 iOS 8——引自于维基百科:
在创建HelloWorld的过程中,我们生成了很多攵件(展开Xcode左边的项目导航视图可以看到如图2-8所示),它们各自的作用是什么彼此间又是怎样的一种关系呢?
在访问资源文件时文件夹和组是有区别的。访问文件夹中的资源时需要将文件夹作为路径。如果icon.png文件放在image文件夹下则访问它的路径是image/icon.png;如果image是组,则访问咜的路径是icon.png
我们主要的编码工作就是在AppDelegate
和ViewController
这两个类中进行的,它们的类图如图2-9所示
ViewController
类继承自UIViewController
类,它是视图控制器类在工程中扮演着根视图和用户事件控制类的角色。
AppDelegate
类是应用程序委托对象这个类中继承的一系列方法在应用生命周期的不同阶段会被回调,其定义如下:
作为应用程序的委托对象AppDelegate
类在应用生命周期的不同阶段会回调不同的方法。首先让我们先了解一下iOS应用的不同状态及其彼此间的关系,如图2-10所示
下面简要介绍一下iOS应用的5种状态。
在应鼡状态跃迁的过程中iOS系统会回调AppDelegate
中的一些方法,并且发送一些通知实际上,在应用的生命周期中用到的方法和通知很多我们选取了幾个主要的方法和通知进行详细介绍,具体如表2-1所示
表2-1 状态跃迁过程中应用回调的方法和本地通知
应用启动并进行初始化时会调用该方法并发出通知。这个阶段会实例化根视图控制器 |
应用进入前台并处于活动状态时调用该方法并发出通知这个阶段可以恢复UI的状态(例洳游戏状态等) |
应用从活动状态进入到非活动状态时调用该方法并发出通知。这个阶段可以保存UI的状态(例如游戏状态等) |
应用进入后台時调用该方法并发出通知这个阶段可以保存用户数据,释放一些资源(例如释放数据库资源等) |
应用进入到前台但是还没有处于活动狀态时调用该方法并发出通知。这个阶段可以恢复用户数据 |
应用被终止时调用该方法并发出通知但内存清除时除外。这个阶段释放一些資源也可以保存用户数据 |
为了便于观察应用程序的运行状态,我们在AppDelegate
类中的方法内添加一些日志输出具体代码如下:
为了让大家更直觀地了解各状态与其相应的方法、通知间的关系,下面我们以几个应用场景为切入点进行系统分析
场景描述:用户点击应用图标的时候,可能是第一次启动这个应用也可能是应用终止后再次启动。该场景的状态跃迁过程见图2-11共经历两个階段3个状态:Not running→Inactive→Active。
图2-11 应用启动场景的状态跃迁过程
场景描述:应用处于运行状态(即Active状态)时点击Home键应鼡会退出。该场景的状态跃迁过程可以分成两种情况:可以在后台运行或者挂起和未挂起不可以在后台运行或者挂起和未挂起。根据工程属性文件(如Info.plist)中的相关属性Application does not run in
状态跃迁的第一种情况:应用可以在后台运行或者挂起和未挂起该场景的状态跃迁过程见图2-13,共经历3个階段4个状态:Active→Inactive→Background→Suspended
图2-13 应用在后台运行或者挂起和未挂起
图2-14 应用不可以在后台运行或者挂起和未挂起
iOS在iOS 4之前不支持多任务点击Home键时,应用会退出并中断;洏在iOS 4之后(包括iOS 4)操作系统能够支持多任务处理,轻按一下Home键时应用会进入后台但不会中断(内存不够的情况除外)
应用在后台也可鉯进行部分处理工作,处理完成后进入挂起和未挂起状态
轻按两下Home键可以快速进入iOS多任务栏,图2-15是iOS 9及其后续版本的多任务栏此时可以看到处于后台运行或挂起和未挂起状态的应用,也可能有处于终止状态的应用向上滑动应用界面,可以删除这些应用并释放内存
图2-15 iOS 9忣其后续版本的多任务栏
场景描述:挂起和未挂起状态的应用重新运行。该场景的状态跃迁过程如图2-16所示囲经历3个阶段4个状态:Suspended→Background→Inactive→Active。
图2-16 挂起和未挂起重噺运行场景的状态跃迁过程
场景描述:应用在后台处理完成时进入挂起和未挂起状态(这是一种休眠状态),洳果这时发出低内存警告为了满足其他应用对内存的需要,该应用就会从内存中清除从而终止运行该场景的状态跃迁过程如图2-17所示。
圖2-17 内存清除场景
内存清除的时候应用终止运行内存清除有两种情况,可能是系统强制清除内存也可能是由使用者从任务栏中手动清除(即删掉应用)。内存清除后如果应用再次运行上一次的运行状态不会被保存,相当于应用第一次运行
在内存清除场景下,应用不會调用任何方法也不会发出任何通知。
YES)这项操作就属于产品属性的设置。在Xcode中产品与目标直接相关,而目标(Target)与工程(Project)直接楿关
我们首先解释一下前面提到的目标概念,一个目标就是一个编译后的产品图2-18所示的界面是使用Xcode创建的HelloWorld工程。一个工程中可以包含哆个目标一个目标包含了一些源程序文件、资源文件和编译说明文件等内容,其中编译说明文件通过“编译参数设置”(Build Settings)和“编译阶段”(Build Phases)设置
在目标列表上面还有一个工程,其中也包含一些“编译参数设置”和“编译阶段”设置项目目标继承了工程的设置,而苴还可以覆盖工程的设置
我们可以在Xcode工程中添加更多的目标,下面就为之前使用故事板实现的HelloWorld工程增加一个目标
图2-19 选择模板对话框
嘫后点击Next按钮,此时会出现如图2-20所示的对话框该对话框与新工程对话框非常类似。
图2-20 目标的一些选项设定
要指定运行哪一个目标可鉯通过选择不同的方案(Scheme)来实现。如图2-22所示在Xcode的左上角选择TestTarget→iPhone 7,就可以在iPhone 7模拟器上运行TestTarget了
什么是方案(Scheme)?在Xcode中方案是指一个要編译执行的目标,其中包括编译这个目标的配置信息以及运行目标的测试方案。一个Xcode工程中可以包含多个方案但每次只能有一个是活動方案。要修改方案可以在图2-22所示的下拉菜单中选择Edit Scheme,此时会弹出如图2-23所示的对话框在其中进行设置即可。
Xcode中嘚目标设置继承自工程设置对于目标和工程下都有的一些设置项,我们可根据需要对目标进行再设置此设置可覆盖工程的设置。
工程Φ的属性设置相对比较简单大家可以参考官方的相关资料。这里介绍目标中两个常用的产品属性
如图2-24所示,在导航面板中选择TestTarget然后茬右侧选择General选项卡,此时可以发现下面的Device Orientation区域中有4个复选框它们代表设备支持的4个方向,选中则代表支持该指定方向
图2-24 设定支持的屏幕方向
如何在模拟器上旋转屏幕方向?我们可以在模拟器运行后通过快捷键“command + 方向键”实现屏幕方向旋转。
图2-25 设置设备支持情况
事實上产品的相关属性还有很多,我们会在后面继续了解
苹果的iOS API在不同版本间有很多变化,本书采用的是iOS 10本节中,我们会介绍iOS 10有哪些API说明如何使用这些API的帮助文档。
对于初学者来说学会在Xcode中使用API帮助文档是非常重要的,下面通过一个例子来介绍API帮助文檔的用法
在编写HelloWorld程序时,可以看到ViewController的代码如果我们对didReceiveMemoryWarning
方法感到困惑,可以查找帮助文档如果只是简单查看帮助信息,可以选中该方法然后选择右边的快捷帮助检查器,如图2-27所示
在打开的Xcode快捷帮助检查器窗口中可以看到该方法的描述,其中包括使用的iOS版本、相关主題以及一些相关示例这里需要说明的是,如果需要查看官方的示例直接从这里下载即可。
如果想查询比较完整的、全面的帮助文档鈳以按住Alt键双击didReceiveMemoryWarning
方法名,此时会打开一个API帮助搜索结果窗口(如图2-28所示)然后选择感兴趣的主题,进入API帮助界面(如图2-29所示)
图2-28 API帮助搜索结果窗口
在本章中,我们首先通过HelloWorld工程讨论了iOS工程模板、应用的运行机制和生命周期然后介绍了几项常用产品属性的设置。最后我们向大家介绍了API帮助文档的用法。
关于iOS使用程序关键是要知道你嘚使用程序是不是正在前台或后台运转。由于体系资源在iOS设备上较为有限一个使用程序有必要在后台与前台有不一样的行动。操作体系吔会约束你的使用程序在后台的运转以提高电池寿数,并提高用户与前台使用程序的体会当使用程序在前台和后台之间切换时,操作體系将会告诉您的使用程序你能够经过这些告诉来修改你的使用程序的行动。
当你的使用程序在前台活动时体系会发送接触作业给它進行处理。在UIKit的基础设施做了大多数的作业传递给你的自定义目标作业一切您需求做的是掩盖在相应的目标的办法来处理这??些作业。关於控件UIKit会经过处理你的接触作业,或许别的一些风趣的作业发生时调用您的自定义代码比方当文本字段中的值更改。
Inactive未激活:程序在湔台运转不过没有接纳到作业。在没有作业处理状况下程序一般停留在这个状况
Active激活:程序在前台运转并且接纳到了作业。这也是前囼的一个正常的模式
Backgroud后台:程序在后台并且能履行代码,大多数程序进入这个状况后会在在这个状况上停留一会时刻到之后会进入挂起和未挂起状况(Suspended)。有的程序经过特别的恳求后能够长时刻处于Backgroud状况
Suspended挂起和未挂起:程序在后台不能履行代码。体系会主动把程序成为这個状况并且不会发出告诉当挂起和未挂起时,程序仍是停留在内存中的当体系内存低时,体系就把挂起和未挂起的程序铲除掉为前囼程序供给更多的内存。
2、各个程序运转状况时署理的回调
①告诉署理进程发动但还没进入状况保留
②告诉署理发动基本完成程序预备开端运转
③当使用程序即将入非活动状况履行在此期间,使用程序不接纳音讯或作业比方来电话
④当使用程序进入活动状况履行
⑤当程序被推送到后台的时分调用。所以要设置后台持续运转则在这个函数里面设置即可
⑥当程序从后台即将从头回到前台时分调用
⑦当程序即将退出是被调用,一般是用来保留数据和一些退出前的整理作业这个需求要设置UIApplicationExitsOnSuspend的键值
按下Home键回来主界面:
3、加载使用程序进入前台
4、加载使用程序进入后台
5、根据警告式呼应中止
①中止timer 和别的周期性的使命
②中止任何正在运转的恳求
④假如是游戏那就暂停它
⑥挂起和未挂起任何分发的行列和不重要的操作行列(你能够持续处理网络恳求或别的时刻灵敏的后台使命)
当使用程序进入后台时,咱们应当做些啥
保留用户数据或状况信息,一切没写到磁盘的文件或信息在进入后台时,最终都写到磁盘去由于程序可能在后台被杀死。
开释盡可能开释的内存
假如还需求长时刻的运转使命,能够在该办法中调用
使用程序在后台时的内存运用:恳求后台运转时刻和发动线程来運转长时刻运转的使命
在后台时,每个使用程序都应当开释最大的内存体系尽力的保持更多的使用程序在后台一起 运转。不过当内存鈈足时会停止一些挂起和未挂起的程序来收回内存,那些内存最大的程序首要被停止
事实上,使用程序应当的目标假如不再运用了那就应当尽快的去掉强引证,这么编译器能够收回这些内存假如你想缓存一些目标提高程序的功能,你能够在进入后台时把这些目标詓掉强引证。
下面这么的目标应当尽快的去掉强引证:
②你能够从头加载的 大的视频或数据文件
③任何没用并且能够容易创立的目标
在后囼时为了削减程序占用的内存,体系会主动在收回一些体系协助你开辟的内存比方:
②去掉任何体系引证的缓存图像
③去掉体系管理數据缓存强引证
在暂停状况的使用程序有必要预备处理任何排队的告诉时,它回来到前台或后台履行状况暂停的使用程序不履行任何代碼,因而不能处理与方向的改变时刻的改变,偏好的改变以及很多别的会影呼使用程序的外观或状况的告诉。为了确保这些更改不会丟失体系排队很多有关的告诉,并把它们传递给使用程序只需它开端再次履行代码(无论是在远景或布景)。为了避免由偏快转为超載与它康复时告诉您的使用程序该体系凝集作业,并供给一个单一的告诉(每个有关类型)反映了净改变,由于你的使用程序被暂停
程序只需契合以下状况之一,只需进入后台或挂起和未挂起状况就会停止:
②app是根据iOS4.0之前体系开发的
app假如停止了,体系会调用app的署理嘚办法 - (void)applicationWillTerminate:(UIApplication *)application这么能够让你能够做一些整理作业。你能够保留一些数据或app的状况这个办法也有5秒钟的约束。超时后办法会回来程序从内存中鏟除
留意:用户能够手工封闭使用程序。
Main Run Loop负责处理用户有关的作业UIApplication目标在程序发动时发动main run Loop,它处理作业和更新视图的界面看Main Run Loop就知道,它是运转在程序的主线程上的这么确保了接纳到用户有关操作的作业是按次序处理的。
用户操作设备有关的操作作业被体系生成并經过UIKit的指定端口分发。作业在内部排成行列一个个的分发到Main run loop 去做处理。UIApplication目标是第一个接纳到时刻的目标它决议作业怎么被处理。接触莋业分发到主窗口窗口再分发到对应动身接触作业的View。别的的作业经过别的路径分发给别的目标变量做处理
object,不过作业也能够传递给別的目标比方,假如view目标不处理作业能够传给父类view或许view controller。