iOS程序启动过程
- 执行
Main
函数 - 执行
UIApplication Main
函数 - 初始化
UIApplication(创建设置代理对象,进入RunLoop循环)
UIApplication
-
UIApplication
是一个iOS程序的象征 - 每个程序都只有一个
UIApplication
, 该对象是单例对象 - 使用
UIApplication
可以做一些应用级的操作-
applicationIconBadgeNumber
: 设置提醒数字 -
networkActivityIndicatorVisible
: 联网指示器是否可见
-
UIWindow
-
UIWindow
是一种特殊的UIView
, 每个App中至少有一个UIWindow
-
iOS
程序启动后, 创建的第一个控件就是UIWindow
, 第二创建控制器的view
, 最后将view
添加到UIWindow
上 - 没有
UIWindow
, 就看不到任何UI界面
-
当多可
UIWindow
存在时, 只有keyWindow
才能与用户交互
多控制器
- 为了便于管理控制器,
iOS
提供了两个特殊的控制器UINavigationController
UITabBarController
UINavigationController
- 使用步骤:
- 初始化
- 设置为
UIWindow
的rootViewController
为UINavigationController
- 根据具体情况, 子控制器进行
push
或pop
UIStoryboardSegue
-
Storyboard
上每一根用来界面跳转的线,都是一个UIStoryboardSegue
对象(简称Segue
) - 根据跳转方式可分为两种类型
-
自动型:点击某个控件后(比如按钮),自动执行
Segue
,自动完成界面跳转 -
手动型:需要通过写代码手动执行
Segue
,才能完成界面跳转[self performSegueWithIdentifier:@"login2contacts" sender:nil];
-
Segue
必须由来源控制器来执行,也就是说,这个perform
方法必须由来源控制器来调用
-
自动型:点击某个控件后(比如按钮),自动执行
多控制器数据传递方式
- 顺传
- 逆传
- 传递方式推荐:使用代理, 或监听-发布
UITabBarController
- 使用步骤
- 初始化控件
- 设置
UIWindow
的rootViewController
- 根据具体情况, 通过
addChildViewController
添加子控制器
Modal
- 除了
push
之外, 还有modal
切换控制器 任何控制器都可以使用Modal的形式展示出来
-
Modal
默认效果是从下至上, 直到覆盖整个屏幕
事件
- iOS中的事件可以分为3大类
- 触摸事件
- 加速事件
- 远程控制事件
- 注意
- 只有继承了
UIResponse
的对象才能处理事件, 它们称之为响应者对象
-
UIApplication
、UIViewController
、UIView
都继承自UIResponder
,因此它们都是响应者对象
,都能够接收并处理事件
- 只有继承了
UITouch
- 当用户用一根手指触摸屏幕时,会创建一个与手指相关联的
UITouch
对象 - 一根手指对应一个
UITouch
对象 -
UITouch
的作用- 保存着跟手指相关的信息,比如触摸的位置、时间、阶段
- 当手指移动时,系统会更新同一个
UITouch
对象,使之能够一直保存该手指在的触摸位置 - 当手指离开屏幕时,系统会销毁相应的
UITouch
对象
提示:iPhone开发中,要避免使用双击事件!
事件的产生和传递
- 发生触摸事件后,系统会将该事件加入到一个由
UIApplication
管理的事件队列中 -
UIApplication
会从事件队列中取出最前面的事件,并将事件分发下去以便处理,通常,先发送事件给应用程序的主窗口(keyWindow)
- 主窗口会在视图层次结构中
找到一个最合适的视图
来处理触摸事件,这也是整个事件处理过程的第一步 - 找到合适的视图控件后,就会调用视图控件的
touches
方法来作具体的事件处理
Quartz2D
-
Quartz 2D
是一个二维绘图引擎,同时支持iOS
和Mac
系统 -
Quartz 2D
能完成的工作- 绘制图形 : 线条\三角形\矩形\圆\弧等
- 绘制\生成图片(图像)
- ...
-
Quartz2D
的API是纯C语言的 -
Quartz2D
的API来自于Core Graphics框架
- 数据类型和函数基本都以
CG
作为前缀
自定义View
- 如何利用
Quartz2D
绘制东西到view
上?- 首先,得有图形上下文,因为它能保存绘图信息,并且决定着绘制到什么地方去
- 其次,那个图形上下文必须跟
view
相关联,才能将内容绘制到view
上面
- 自定义
view
的步骤- 新建一个类,继承自
UIView
- 实现
- (void)drawRect:(CGRect)rect
方法,然后在这个方法中- 取得跟当前
view
相关联的图形上下文 - 绘制相应的图形内容
- 利用图形上下文将绘制的所有内容渲染显示到
view
上面
- 取得跟当前
- 新建一个类,继承自
CALayer
- 在
iOS
中,你能看得见摸得着的东西基本上都是UIView
,比如一个按钮、一个文本标签、一个文本输入框、一个图标等等,这些都是UIView
-
UIView
之所以能显示在屏幕上,完全是因为它内部的一个CALayer图层
- 在创建
UIView
对象时,UIView
内部会自动创建一个图层(即CALayer对象)
,通过UIView
的layer
属性可以访问这个层 - 当
UIView
需要显示到屏幕上时,会调用drawRect:
方法进行绘图,并且会将所有内容绘制在自己的图层上,绘图完毕后,系统会将图层拷贝到屏幕上,于是就完成了UIView
的显示 -
UIView
本身不具备显示的功能,是它内部的图层CALayer
才有显示功能 - 通过操作
CALayer
对象,可以很方便地调整UIView
的一些外观属性,比如- 阴影
- 圆角大小
- 边框宽度和颜色
- ...
隐式动画
-
每一个
UIView
内部都默认关联着一个CALayer
,我们可用称这个Layer
为Root Layer(根层)
-
所有的
非Root Layer
,也就是手动创建的CALayer对象
,都存在着隐式动画
-
什么是隐式动画?
- 当对
非Root Layer
的部分属性进行修改时,默认会自动产生一些动画效果
而这些属性称为Animatable Properties(可动画属性)
- 当对
-
列举几个常见的
Animatable Properties:
-
bounds
:用于设置CALayer
的宽度和高度。修改这个属性会产生缩放动画 -
backgroundColor
:用于设置CALayer
的背景色。修改这个属性会产生背景色的渐变动画 -
position
:用于设置CALayer
的位置。修改这个属性会产生平移动画
-
核心动画
-
Core Animation
简介-
Core Animation
,中文翻译为核心动画,它是一组非常强大的动画处理API
,使用它能做出非常炫丽的动画效果,而且往往是事半功倍。也就是说,使用少量的代码就可以实现非常强大的功能。 -
Core Animation
可以用在Mac OS X
和iOS
平台。 -
Core Animation
的动画执行过程都是在后台操作的,不会阻塞主线程。 -
Core Animation
是直接作用在CALayer
上的,并非UIView
-
转场动画: CATransition
-
CATransition
是CAAnimation
的子类,用于做转场动画,能够为层提供移出屏幕和移入屏幕的动画效果
。iOS比Mac OS X的转场动画效果少一点 -
UINavigationController
就是通过CATransition
实现了将控制器的视图推入屏幕的动画效果
CADisplayLink
-
CADisplayLink
是一种以屏幕刷新频率触发的时钟机制,每秒钟执行大约60次左右
-
CADisplayLink
是一个计时器,可以使绘图代码与视图的刷新频率保持同步,而NSTimer
无法确保计时器实际被触发的准确时间 - 使用方法:
- 定义
CADisplayLink
并制定触发调用方法 - 将显示链接添加到主运行循环队列
- 定义
进程
-
进程
是指在系统中正在运行的一个应用程序
- 每个
进程
之间是独立
的,每个进程
均运行在其专用且受保护的内存空间内 - 比如同时打开迅雷、Xcode,系统就会分别启动2个进程
线程
- 1个
进程
要想执行任务,必须得有线程(每1个进程至少要有1条线程)
一个进程(程序)的所有任务都在线程中执行
线程的串行
- 1个线程中任务的执行是
串行
的- 1个线程中执行多个任务,那么只能一个一个地
按顺序执行
这些任务 - 也就是说,
在同一时间内,1个线程只能执行1个任务
- 1个线程中执行多个任务,那么只能一个一个地
多线程
- 1个
进程
中可以开启多条线程
,多条线程可以并行(同时)执行不同的任务
- 进程(车间) > 线程(车间工人)
多线程技术可以提高程序的执行效率
多线程的原理
-
同一时间,CPU只能处理1条线程
,只有1条线程在工作(执行) -
多线程并发(同时)执行
,其实是CPU快速地在多条线程之间调度(切换)
- 如果CPU调度线程的时间足够快,就造成了多线程并发执行的假象
-
思考:如果线程非常非常多,会发生什么情况?
- CPU会在N多线程之间调度,CPU会累死,消耗大量的CPU资源
- 每条线程被调度执行的频次会降低(线程的执行效率降低)
多线程的优缺点
- 多线程的优点
- 能适当提高程序的执行效率
- 能适当提高资源利用率(CPU、内存利用率)
- 多线程的缺点
- 创建线程是有开销的,iOS下主要成本包括:内核数据结构(大约1KB)、栈空间(子线程512KB、主线程1MB,也可以使用-setStackSize:设置,但必须是4K的倍数,而且最小是16K),创建线程大约需要90毫秒的创建时间
- 如果开启大量的线程,会降低程序的性能
- 线程越多,CPU在调度线程上的开销就越大
- 程序设计更加复杂:比如线程之间的通信、多线程的数据共享
GCD
- 什么是GCD?
- 全称是
Grand Central Dispatch
,可译为牛逼的中枢调度器
- 纯C语言,提供了非常多强大的函数
- 全称是
- GCD的优势
- GCD是苹果公司为
多核
的并行运算
提出的解决方案 - GCD会自动利用更多的CPU内核(比如双核、四核)
- GCD会
自动管理线程的生命周期(创建线程、调度任务、销毁线程)
- 程序员只需要告诉GCD想要执行什么任务,不需要编写任何线程管理代码
- GCD是苹果公司为
-
GCD中有2个核心概念
-
任务
:执行什么操作 -
队列
:用来存放任务
-
-
GCD的使用2个步骤
-
定制任务
- 确定想做的事情
-
将任务添加到队列中
- GCD会自动将队列中的任务取出,放到对应的线程中执行
- 任务的取出遵循队列的
FIFO原则
:先进先出,后进后出
-
- 队列的类型
-
并发队列(Concurrent Dispatch Queue)
- 可以让多个任务并发(同时)执行(自动开启多个线程同时执行任务)
并发功能只有在异步(dispatch_async)函数下才有效
-
串行队列(Serial Dispatch Queue)
- 一个任务执行完毕后,再执行下一个任务
-
NSOperation
-
NSOperation
的作用- 配合使用
NSOperation
和NSOperationQueue
也能实现多线程编程
- 配合使用
-
NSOperation
和NSOperationQueue
实现多线程的具体步骤- 先将需要执行的操作封装到一个
NSOperation
对象中 - 然后将
NSOperation
对象添加到NSOperationQueue
中 - 系统会自动将
NSOperationQueue
中的NSOperation
取出来 - 将取出的
NSOperation
封装的操作放到一条新线程中执行
- 先将需要执行的操作封装到一个
-
NSOperation
的子类-
NSOperation
是个抽象类,并不具备封装操作的能力,必须使用它的子类
-
-
使用
NSOperation
子类的方式有3种NSInvocationOperation
NSBlockOperation
- 自定义子类继承
NSOperation
,实现内部相应的方法
RunLoop
RunLoop对象
-
iOS中有2套API来访问和使用
RunLoop
-
Foundation
NSRunLoop
-
Core Foundation
CFRunLoopRef
-
-
NSRunLoop
和CFRunLoopRef
都代表着RunLoop
对象 -
NSRunLoop
是基于CFRunLoopRef
的一层OC包装,所以要了解RunLoop
内部结构,需要多研究CFRunLoopRef
层面的API(Core Foundation层面)
RunLoop资料
CFRunLoopRef是开源的
http://opensource.apple.com/source/CF/CF-1151.16/
RunLoop与线程
-
每条线程都有唯一的一个与之对应的
RunLoop
对象 -
主线程的RunLoop已经自动创建好了
,子线程的RunLoop需要主动创建
-
RunLoop在第一次获取时创建,在线程结束时销毁
URL
-
什么是URL
- URL的全称是
Uniform Resource Locator
(统一资源定位符) - 通过1个URL,能找到互联网上唯一的1个资源
- URL就是资源的地址、位置,
互联网上的每个资源都有一个唯一的URL
- URL的全称是
-
URL的基本格式 = 协议://主机地址/路径
-
协议
:不同的协议,代表着不同的资源查找方式、资源传输方式 -
主机地址
:存放资源的主机(服务器)的IP地址(域名) -
路径
:资源在主机(服务器)中的具体位置
URL中常见的协议
-
HTTP
- 超文本传输协议,访问的是远程的网络资源,格式是http://
http协议是在网络开发中最常用的协议
-
file
- 访问的是本地计算机上的资源,格式是file://(不用加主机地址)
-
mailto
- 访问的是电子邮件地址,格式是mailto:
-
FTP
- 访问的是共享主机的文件资源,格式是ftp://
HTTP协议的作用
-
HTTP
的全称是Hypertext Transfer Protocol,超文本传输协议
- 规定客户端和服务器之间的数据传输格式
- 让客户端和服务器能有效地进行数据沟通
HTTP协议的特点
-
简单快速
- 因为HTTP协议简单,所以HTTP服务器的程序规模小,因而通信速度很快
-
灵活
- HTTP允许传输各种各样的数据
-
HTTP 0.9和1.0使用非持续连接
- 限制每次连接只处理一个请求,服务器对客户端的请求做出响应后,马上断开连接,这种方式可以节省传输时间
HTTP的基本通信过程
- 完整的http通信可以分为2大步骤
请求:客户端向服务器索要数据
响应:服务器返回客户端相应的数据
HTTP POST GET
- 在HTTP/1.1协议中,定义了8种发送http请求的方法
GET、POST、OPTIONS、HEAD、PUT、DELETE、TRACE、CONNECT、PATCH
- 根据HTTP协议的设计初衷,不同的方法对资源有不同的操作方式
- PUT :增
- DELETE :删
- POST:改
- GET:查
- 最常用的是GET和POST(实际上GET和POST都能办到增删改查)
GET和POST对比
- GET和POST的主要区别表现在数据传递上
-
GET
*在请求URL后面以?的形式跟上发给服务器的参数,多个参数之间用&隔开,比如
http://ww.test.com/login?username=123&pwd=234&type=JSON
由于浏览器和服务器对URL长度有限制,因此在URL后面附带的参数是有限制的,通常不能超过1KB -
POST
- 发给服务器的参数全部放在请求体中
理论上,POST传递的数据量没有限制(具体还得看服务器的处理能力)
- 发给服务器的参数全部放在请求体中
-
GET和POST的选择
- 选择GET和POST的建议
- 如果要
传递大量数据,比如文件上传,只能用POST请求
-
GET的安全性比POST要差些
,如果包含机密\敏感信息,建议用POST - 如果
仅仅是索取数据(数据查询),建议使用GET
- 如果是
增加、修改、删除数据,建议使用POST
HTTP通信过程 - 请求
- HTTP协议规定:1个完整的由客户端发给服务器的HTTP请求中包含以下内容
// 请求头:包含了对客户端的环境描述、客户端请求信息等
GET /minion.png HTTP/1.1 // //包含了请求方法、请求资源路径、HTTP协议版本
Host: 120.25.226.186:32812 // 客户端想访问的服务器主机地址
User-Agent: Mozilla/5.0 // 客户端的类型,客户端的软件环境
Accept: text/html, */* // 客户端所能接收的数据类型
Accept-Language: zh-cn // 客户端的语言环境
Accept-Encoding: gzip // 客户端支持的数据压缩格式
// 请求体:客户端发给服务器的具体数据,比如文件数据(POST请求才会有)
HTTP通信过程 - 响应
- 客户端向服务器发送请求,服务器应当做出响应,即返回数据给客户端
// HTTP协议规定:1个完整的HTTP响应中包含以下内容
// 响应头:包含了对服务器的描述、对返回数据的描述
HTTP/1.1 200 OK // 包含了HTTP协议版本、状态码、状态英文名称
Server: Apache-Coyote/1.1 // 服务器的类型
Content-Type: image/jpeg // 返回数据的类型
Content-Length: 56811 // 返回数据的长度
Date: Mon, 23 Jun 2014 12:54:52 GMT // 响应的时间
// 响应体:服务器返回给客户端的具体数据,比如文件数据
iOS中发送HTTP请求的方案
-
在iOS中,常见的发送HTTP请求的方案有
- 苹果原生(自带)
-
NSURLConnection
:用法简单,最古老最经典最直接的一种方案【坑比较多】 -
NSURLSession
:功能比NSURLConnection更加强大,苹果目前比较推荐使用这种技术【2013推出,iOS7开始出的技术】 -
CFNetwork
:NSURL*的底层,纯C语言
-
第三方框架
-
ASIHttpRequest
:外号“HTTP终结者”,功能极其强大,可惜早已停止更新 -
AFNetworking
:简单易用,提供了基本够用的常用功能,维护和使用者多 -
MKNetworkKit
:简单易用,维护和使用者少
-
NSURLConnection
- 使用
NSURLConnection
发送请求的步骤-
创建一个
NSURL对象,设置请求路径` 传入NSURL创建一个NSURLRequest对象,设置请求头和请求体
使用NSURLConnection发送请求
-
JSON
- 什么是
JSON
?-
JSON
是一种轻量级的数据格式,一般用于数据交互
服务器返回给客户端的数据,一般都是JSON格式或者XML格式(文件下载除外)
-
// JSON的格式很像OC中的字典和数组
{"name" : "jack", "age" : 10}
{"names" : ["jack", "rose", "jim"]}
// 标准JSON格式的注意点:key必须用双引号
- 要想从JSON中挖掘出具体数据,得对JSON进行解析
JSON 转换为 OC数据类型
JSON解析方案
- 在iOS中,JSON的常见解析方案有4种
- 第三方框架:
JSONKit
、SBJson
、TouchJSON
(性能从左到右,越差) - 苹果原生(自带):
NSJSONSerialization
(性能最好)
- 第三方框架:
Reachability
-
在网络应用中,需要对用户设备的网络状态进行实时监控,目的是
-
让用户了解自己的网络状态,防止一些误会(比如怪应用无能)
-
根据用户的网络状态进行智能处理,节省用户流量,提高用户体验
- WIFI\3G网络:自动下载高清图片
- 低速网络:只下载缩略图
- 没有网络:只显示离线的缓存数据
-
苹果官方提供了一个叫Reachability的示例程序,便于开发者检测网络状态
NSURLSession
-
NSURLSession
是iOS7中新的网络接口,它与NSURLConnection
是并列的。在程序在前台时,NSURLSession
与NSURLConnection
可以互为替代工作。注意,如果用户强制将程序关闭,NSURLSession会断掉 -
使用步骤
- 使用
NSURLSession
对象创建Task
,然后执行Task
- 使用
-
Task的类型
-
NSURLSessionTask
-
NSURLSessionDataTask
NSURLSessionUploadTask
NSRULSessionDownloadTask
-
-
-
详细介绍 (别人家的博客)
NSURLSessionConfiguration
-
NSURLSessionConfiguration对象用于初始化NSURLSession对象。
-
展开请求级别中与
NSMutableURLRequest
相关的可供选择的方案,我们可以看到NSURLSessionConfiguration
对于会话如何产生请求,提供了相当多的控制和灵活性。从网络访问性能,到cookie,安全性,缓存策略,自定义协议,启动事件设置,以及用于移动设备优化的几个新属性,你会发现你一直在寻找的,正是NSURLSessionConfiguration
。 -
会话在初始化时复制它们的配置,
NSURLSession
有一个只读的配置属性,使得该配置对象上的变化对这个会话的政策无效。配置在初始化时被读取一次,之后都是不会变化的。 -
想要查看更多关于后台会话的信息,可以查看WWDC Session 204: “What’s New with Multitasking”
AFN
-
什么是AFN?
- 全称是
AFNetworking
,是对NSURLConnection的一层封装
- 虽然运行效率没有ASI高,但是使用比ASI简单
在iOS开发中,使用比较广泛
- 全称是
-
AFN的github地址
UIWebView
-
什么是
UIWebView
?-
UIWebView
是iOS内置的浏览器控件 系统自带的Safari浏览器就是通过UIWebView实现的
-
-
UIWebView
不但能加载远程的网页资源,还能加载绝大部分的常见文件- html\htm
- pdf、doc、ppt、txt
- mp4
- … …
-
UIWebView
常用的加载资源的方法- (void)loadRequest:(NSURLRequest *)request;
网友评论