美文网首页iOS Developer
适用于iOS的应用程序编程指南(二)

适用于iOS的应用程序编程指南(二)

作者: nicedayCoco | 来源:发表于2017-05-15 18:19 被阅读132次

    应用程序生命周期

    应用程序是您的代码和系统框架之间相互作用的结果。系统框架提供所有应用程序需要运行的基本架构,并提供自定义基础架构所需的代码,并为应用程序提供所需的外观。知道这些有助于了解iOS基础架构及其运作方式。

    iOS框架依赖于设计模式,如模型 - 视图 - 控制器和代理模式。了解这些设计模式对于成功创建应用程序至关重要。并且有助于熟悉Objective-C语言及其功能。如果您是iOS编程的新手,请阅读开始开发iOS应用程序(Swift)Start Developing iOS Apps (Swift) 以了解iOS应用程序和Objective-C语言。

    主要功能

    每个基于C的应用程序的切入点是主要功能,iOS应用程序没有什么不同。不同之处在于,对于iOS应用,您不能自己编写主要功能。相反,Xcode将创建此功能作为您的基本项目的一部分。清单2-1显示了此函数的示例。除了少数情况,您不应该更改Xcode提供的主要功能的实现。

    清单2-1 iOS应用程序的主要功能

    #import#import "AppDelegate.h"

    int main(int argc, char * argv[])

    {

    @autoreleasepool {

    return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));

    }

    }

    关于主要功能的唯一要点是它的工作是控制UIKit框架。 UIApplicationMain功能通过创建应用程序的核心对象,从可用的故事板文件中加载应用程序的用户界面,调用自定义代码,以便您有机会进行一些初始设置,并将应用程序的运行循环(run loop)。您提供的唯一的部分是故事板文件和自定义初始化代码。

    应用程序的结构

    在启动过程中,UIApplicationMain函数设置了几个关键对象,并启动应用程序运行。每个iOS应用程序的核心是UIApplication对象,其工作是促进系统与应用程序中的其他对象之间的交互。图2-1显示了大多数应用程序中常见的对象,而表2-1列出了每个对象的角色。首先要注意的是iOS应用程序使用模型视图 - 控制器架构。这种模式将应用程序的数据和业务逻辑与该数据的可视化呈现分开。这种架构对于创建可以在具有不同屏幕尺寸的不同设备上运行的应用程序至关重要。

    图2-1 iOS应用程序中的关键对象

    表2-1对象在iOS应用程序中的作用

    UIApplication

    object

    UIApplication对象管理事件循环和其他高级应用程序行为。它还会向其委托报告关键应用程序转换和一些特殊事件(如传入推送通知),这是您定义的自定义对象。使用UIApplication对象,就是没有子类化。


    App delegate

    object

    应用程序代理是您的自定义代码的核心。该对象与UIApplication对象一起工作,以处理应用程序初始化,状态转换和许多高级应用程序事件。这个对象也是唯一一个保证在每个应用程序中出现的对象,因此通常用于设置应用程序的初始数据结构。


    Documents and data model

    objects

    数据模型对象存储您的应用程序的内容,并针对您的应用程序。例如,银行应用程序可能存储包含金融交易的数据库,而绘画应用程序可能会存储导致创建该映像的图像对象或甚至绘制命令序列。 (在后一种情况下,图像对象仍然是数据对象,因为它只是图像数据的容器。)

    应用程序还可以使用文档对象(UIDocument的自定义子类)来管理其部分或全部数据模型对象。文档对象不是必需的,但提供了一种方便的方法来对属于单个文件或文件包的数据进行分组。有关文档的更多信息,请参阅基于文档的iOS应用程序编程指南。Document-Based App Programming Guide for iOS


    View controller

    objects

    查看控制器对象在屏幕上管理应用程序内容的显示。视图控制器管理单个视图及其子视图的收集。当显示时,视图控制器通过将其安装在应用程序的窗口中来使其视图可见。

    UIViewController类是所有视图控制器对象的基类。它提供加载视图,呈现它们,旋转它们以响应设备旋转以及其他几种标准系统行为的默认功能。 UIKit和其他框架定义了附加的视图控制器类来实现标准系统接口,如图像选择器,标签栏界面和导航界面。

    有关如何使用视图控制器的详细信息,请参阅“用于iOS的View Controller编程指南”。View Controller Programming Guide for iOS.


    UIWindow

    object

    UIWindow对象协调屏幕上一个或多个视图的呈现。大多数应用程序只有一个窗口,它在主屏幕上显示内容,但应用程序可能会在外部显示器上显示内容的附加窗口。

    要更改应用程序的内容,您可以使用视图控制器更改相应窗口中显示的视图。你永远不会更换窗口本身。

    除了托管视图之外,Windows还可以使用UIApplication对象将事件传递给您的视图和查看控制器。

    View objects, control objects, and layer objects

    视图和控件提供了应用内容的可视化表示。视图是在指定的矩形区域中绘制内容并响应该区域内的事件的对象。控件是一种专门的视图类型,负责实现熟悉的界面对象,如按钮,文本字段和切换开关。

    UIKit框架提供了呈现许多不同类型内容的标准视图。您还可以通过直接对UIView(或其后代)进行子类化来定义自己的自定义视图。

    除了包含视图和控件之外,应用程序还可以将Core Animation图层纳入其视图和控制层次结构中。层对象实际上是表示可视内容的数据对象。视图使用层叠对象集中在幕后渲染其内容。您还可以向界面添加自定义图层对象,以实现复杂的动画和其他类型的复杂视觉效果。

    一个iOS应用程序与另一个iOS应用程序区别在于它管理的数据(和相应的业务逻辑)以及它如何向用户呈现数据。与UIKit对象的大多数交互不会定义您的应用程序,而是帮助您优化其行为。例如,您的应用程序委托的方法让您知道应用程序何时更改状态,以便您的自定义代码可以适当地进行响应。

    主运行环路

    应用程序的主要运行环路处理所有与用户相关的事件。 UIApplication对象在启动时设置主运行环,并使用它来处理事件并处理基于视图的接口的更新。顾名思义,主运行循环在应用程序的主线程上执行。此行为确保与用户相关的事件以其接收的顺序连续处理。

    图2-2显示了主运行循环的架构,以及用户事件如何导致您的应用程序采取的操作。当用户与设备进行交互时,与这些交互相关的事件由系统生成,并通过由UIKit设置的特殊端口传送到应用。事件在应用程序内部排队,并逐个分发到主运行循环以执行。 UIApplication对象是接收事件的第一个对象,并且决定需要做什么。触摸事件通常被分派到主窗口对象,主窗口对象又将其分派到触摸发生的视图。其他事件可能会通过不同应用对象的不同路径。

    图2-2主运行循环中的处理事件

    iOS应用中可以传送许多类型的事件。 最常见的如表2-2所示。 许多这些事件类型是使用您的应用程序的主运行循环传递的,但有些不是。 一些事件被发送到一个委托对象或被传递给你提供的一个块。 有关如何处理大多数类型的事件(包括触摸,遥控,运动,加速度计和陀螺事件)的信息,请参阅UIKit应用程序的事件处理指南。Event Handling Guide for UIKit Apps.

    表2-2 iOS应用程序的常见事件类型

    触摸

    发生事件的视图对象

    视图是响应者对象。 视图未处理的任何触摸事件都将转发到响应者链进行处理。


    遥控

    摇动运动事件

    第一反应者对象

    遥控器事件用于控制媒体播放,并由耳机和其他附件产生。


    加速度计

    磁力计

    陀螺仪

    你指定的对象

    与加速度计,磁力计和陀螺仪硬件有关的事件将传递给您指定的对象。


    位置

    你指定的对象

    您注册使用核心位置框架接收位置事件。 有关使用Core Location的更多信息,请参阅位置和地图编程指南。Location and Maps Programming Guide.


    重绘

    需要更新的视图

    重绘事件不涉及事件对象,而是简单地调用视图来绘制自身。 iOS绘图和打印指南中描述了iOS的绘图体系结构。Drawing and Printing Guide for iOS.

    一些事件,如触摸和遥控事件,由您的应用程序的响应者对象处理。响应者对象在你的应用程序无处不在。 (UIApplication对象,您的视图对象和视图控制器对象都是响应者对象的示例。)大多数事件都针对特定的响应者对象,但如果需要处理事件,则可以将其传递给其他响应者对象(通过响应方链)。例如,不处理事件的视图可以将事件传递到其超级视图或视图控制器。

    在控件(例如按钮)中发生的触摸事件的处理方式与在许多其他类型的视图中发生的触摸事件的处理方式不同。通常只有有限数量的交互可能与控件相关联,因此这些交互被重新包装成动作消息并传递到适当的目标对象。此目标动作设计模式可以方便地使用控件来触发您应用中自定义代码的执行。

    应用程式的执行状态

    在任何给定的时刻,您的应用程序都在表2-3所列的状态之一。系统会将应用程序从状态移动到响应整个系统中发生的操作。例如,当用户按下主页按钮时,进入电话呼叫或发生其他任何中断,当前正在运行的应用程序会响应状态改变。图2-3显示了从状态转移到应用程序时的路径。

    表2-3应用状态

    不运行 Not running

    该应用尚未启动或正在运行,但被系统终止。


    无效 Inactive

    该应用程序正在前台运行,但当前没有收到事件。 (它可能正在执行其他代码。)应用程序通常在短暂转换到不同的状态下停留在此状态。


    活性 Active

    应用程序正在前台运行,并且正在接收事件。这是前台应用程序的正常模式。


    背景 Background

    应用程序在后台执行代码。大多数应用程序暂时进入此状态。然而,请求额外执行时间的应用程序可能会保持在此状态一段时间。此外,直接发送到后台的应用程序进入此状态而不是非活动状态。有关如何在后台执行代码的信息,请参阅后台执行。Background Execution


    已暂停 Suspended

    该应用程序在后台,但不执行代码。系统将应用程序自动移动到这个状态,在这样做之前不通知他们。暂停时,应用程序仍然在内存中,但不执行任何代码。

    当出现低内存条件时,系统可能会清除已暂停的应用程序,而不会通知前台应用程序的空间更大。

    图2-3 iOS应用程序中的状态更改

    大多数状态转换伴随着对应用程序委托对象的方法的相应调用。这些方法是您以适当的方式回应状态变更的机会。下面列出了这些方法,以及如何使用它们的摘要。

    应用程序:willFinishLaunchingWithOptions:这种方法是您的应用程序在启动时执行代码的第一次机会。

    应用程序:didFinishLaunchingWithOptions: - 该方法允许您在应用程序显示给用户之前执行任何最终初始化。

    applicationDidBecomeActive: - 让您的应用程序知道它即将成为前台应用程序。使用此方法进行任何最后一刻的准备。

    applicationWillResignActive:让您知道您的应用程序正在从前台应用程序转移。使用此方法将您的应用程序置于静止状态。

    applicationDidEnterBackground:让您知道您的应用程序现在正在后台运行,并可能随时暂停。

    applicationWillEnterForeground:让您知道您的应用程序正在移出背景并返回到前台,但它尚未激活。

    applicationWillTerminate:让你知道你的应用程序正在被终止。如果您的应用被暂停,则不会调用此方法。

    应用程序终止

    应用程序必须随时准备终止发生,不应等待保存用户数据或执行其他关键任务。系统启动的终止是应用程序生命周期的正常部分。该系统通常终止应用程序,以便它可以回收内存并为用户启动的其他应用程序腾出空间,但系统也可能会终止行为不当或未及时响应事件的应用程序。

    暂停的应用程序终止时不会收到通知;该系统会杀死该进程并回收相应的内存。如果一个应用程序当前在后台运行并且没有挂起,系统会在终止之前调用应用程序委托的applicationWillTerminate:。当设备重新启动时,系统不会调用此方法。

    除系统终止您的应用程序外,用户还可以使用多任务界面显式终止您的应用程序。用户启动的终止与终止挂起的应用程序具有相同的效果。该应用程序的进程被杀死,并且没有通知发送到该应用程序。

    线程和并发

    系统创建您的应用程序的主线程,您可以根据需要创建其他线程来执行其他任务。对于iOS应用,首选技术是使用Grand Central Dispatch(GCD),操作对象和其他异步编程接口,而不是自己创建和管理线程。 GCD等技术可以让您定义想要执行的工作和要执行的顺序,但让系统决定如何在可用的CPU上执行该工作。让系统处理线程管理简化了必须编写的代码,使得更容易确保代码的正确性,并提供更好的整体性能。

    考虑线程和并发时,请考虑以下几点:

    涉及视图,核心动画和许多其他UIKit类的工作通常必须发生在应用程序的主线程上。这个规则有一些例外 - 例如,基于图像的操作通常可能发生在后台线程上 - 但是当有疑问时,假设工作需要在主线程上发生。

    长时间任务(或潜在的长度任务)应始终在后台线程上执行。任何涉及网络访问,文件访问或大量数据处理的任务都应使用GCD或操作对象异步执行。

    在启动时,尽可能将任务从主线程移出。在启动时,您的应用程序应尽可能快地设置用户界面。只有有助于设置用户界面的任务才能在主线程上执行。所有其他任务都应该异步执行,结果一旦准备就显示给用户。

    有关使用GCD和操作对象执行任务的更多信息,请参阅并发编程指南。Concurrency Programming Guide

    相关文章

      网友评论

        本文标题:适用于iOS的应用程序编程指南(二)

        本文链接:https://www.haomeiwen.com/subject/qnwhxxtx.html