原创:知识点总结性文章
创作不易,请珍惜,之后会持续更新,不断完善
个人比较喜爱做笔记和写总结,毕竟好记性不如烂笔头哈哈,这些文章记录了我的IOS成长历程,希望能与大家一起进步
温馨提示:由于简书不支持目录跳转,大家可通过command + F 输入目录标题后迅速寻找到你所需要的内容
目录
- 一、iOS编译过程及原理(字节跳动)
- 1、编程语言
- 2、Clang编译器前端的编译过程
- 3、LLVM编译器后端的编译过程
- 二、系统架构
- 1、Cocoa Touch Layer(触摸UI层)
- 2、MediaLayer(媒体层)
- 3、CoreServices Layer(核心服务层)
- 4、Core OS(核心操作系统层)
一、iOS编译过程及原理
1、编程语言
编译语言
C++、Objective C、Swift都是编译语言,二者的编译都是依赖于Clang + LLVM,采用Clang作为编译器前端,LLVM(Low level vritual machine)作为编译器后端。编译语言在执行的时候,必须先通过编译器生成机器码,机器码可以直接在CPU上执行,所以执行效率较高。
直译式语言
JavaScript、Python都是直译式语言。直译式语言不需要经过编译的过程,而是在执行的时候通过一个中间的解释器将代码解释为CPU可以执行的代码。所以,较编译语言来说,直译式语言效率低一些,但是编写的更灵活。
示例代码
#import <Foundation/Foundation.h>
//注释
#define DEBUG 1
int main(){
#ifdef DEBUG
NSLog(@"DEBUG模式");
#else
NSLog(@"RELEASE模式");
#endif
return 0;
}
2、Clang编译器前端的编译过程
a、预处理
预处理器会处理源文件中的宏定义,将代码中的宏用其对应定义的具体内容进行替换,删除注释,展开头文件,产生 .i文件。
#import <Foundation/Foundation.h>这一行是告知预处理器将这行用Foundation.h中的内容替换,这个过程是递归的,由于Foundation.h中也import了其他文件。使用clang查看预处理结果:
xcrun clang -E main.m
处理后的文件会有许多代码,其中基本上都是引用的其他文件然后被递归替换的内容,划到最底部可以看到main函数。
int main(){
NSLog(@"DEBUG模式");
return 0;
}
所写的注释被删除,条件编译也被处理了。
b、词法分析
读入源文件的字符流,将他们组织为有意义的词素(lexeme)序列。对于每个词素,分析器产生词法单元(token)作为输出,列如大小括号,等于号还有字符串等。 使用clang查看词法分析结果。
xcrun clang -fmodules -fsyntax-only -Xclang -dump-tokens main.m
输出结果为如下。Loc=<main.m:2:1>标示这个token位于源文件main.m的第2行,从第1个字符开始。保存token在源文件中的位置是方便后续clang分析的时候能够找到出错的原始位置。
annot_module_include '#import <Foundation/Foundation.h>
//' Loc=<main.m:2:1>
int 'int' [StartOfLine] Loc=<main.m:5:1>
identifier 'main' [LeadingSpace] Loc=<main.m:5:5>
l_paren '(' Loc=<main.m:5:9>
r_paren ')' Loc=<main.m:5:10>
l_brace '{' Loc=<main.m:5:11>
identifier 'NSLog' [StartOfLine] [LeadingSpace] Loc=<main.m:7:5>
l_paren '(' Loc=<main.m:7:10>
at '@' Loc=<main.m:7:11>
string_literal '"DEBUG模式"' Loc=<main.m:7:12>
r_paren ')' Loc=<main.m:7:25>
semi ';' Loc=<main.m:7:26>
return 'return' [StartOfLine] [LeadingSpace] Loc=<main.m:11:5>
numeric_constant '0' [LeadingSpace] Loc=<main.m:11:12>
semi ';' Loc=<main.m:11:13>
r_brace '}' [StartOfLine] Loc=<main.m:12:1>
eof '' Loc=<main.m:12:2>
c、语法分析
在Clang中由Parser和 Sema 两个模块配合完成验证语法是否正确。根据当前语言的语法,生成语意节点,并将所有节点组合成抽象语法树 AST。简单点来说,就是将词法分析的Token流会被解析成一颗抽象语法树。使用clang查看语法分析结果:
xcrun clang -fsyntax-only -Xclang -ast-dump main.m | open -f
得到的AST结构部分如下。有了抽象语法树,Clang就可以对这个树进行分析,找出代码中的错误。Clang Static Analyzer是开源编译器前端clang中内置的针对C,C++和Objective-C源代码的静态分析工具,能提供普通warning之外的检查,涵盖内存操作,安全等方面。
�[0;33mcol:29�[0m> �[0;32m'void'�[0m�[0;36m�[0m�[0;36m�[0m
�[0;34m| |-�[0m�[0;1;35mImplicitCastExpr�[0m�[0;33m 0x7f978506ccd8�[0m <�[0;33mcol:9�[0m> �[0;32m'void (*)(id, ...)'�[0m�[0;36m�[0m�[0;36m�[0m <�[0;31mFunctionToPointerDecay�[0m>
�[0;34m| | `-�[0m�[0;1;35mDeclRefExpr�[0m�[0;33m 0x7f9785041d00�[0m <�[0;33mcol:9�[0m> �[0;32m'void (id, ...)'�[0m�[0;36m�[0m�[0;36m�[0m �[0;1;32mFunction�[0m�[0;33m 0x7f9785041ba0�[0m�[0;1;36m 'NSLog'�[0m �[0;32m'void (id, ...)'�[0m
�[0;34m| `-�[0m�[0;1;35mImplicitCastExpr�[0m�[0;33m 0x7f978506cd18�[0m <�[0;33mcol:15�[0m, �[0;33mcol:16�[0m> �[0;32m'id':'id'�[0m�[0;36m�[0m�[0;36m�[0m <�[0;31mBitCast�[0m>
�[0;34m| `-�[0m�[0;1;35mObjCStringLiteral�[0m�[0;33m 0x7f978506cc58�[0m <�[0;33mcol:15�[0m, �[0;33mcol:16�[0m> �[0;32m'NSString *'�[0m�[0;36m�[0m�[0;36m�[0m
�[0;34m| `-�[0m�[0;1;35mStringLiteral�[0m�[0;33m 0x7f9785041d58�[0m <�[0;33mcol:16�[0m> �[0;32m'char [12]'�[0m�[0;36m lvalue�[0m�[0;36m�[0m�[0;1;36m
d、静态分析
一旦编译器把源码生成了抽象语法树,编译器就可以对这棵树做分析处理,以找出代码中的错误,列如类型检查:即检查程序中是否有类型错误。例如:如果代码中给某个对象发送了一个消息,编译器会检查这个对象是否实现了这个消息(函数、方法)。
e、类型检查
一般会把类型检查分为两类:动态的和静态的。动态的在运行时做检查,静态的在编译时做检查。以往编写代码时可以向任意对象发送任何消息,在运行时,才会检查对象是否能够响应这些消息。由于只是在运行时做此类检查,所以叫做动态类型。至于静态类型,是在编译时做检查。
f、目标代码的生成与优化
CodeGen
CodeGen 负责将语法树 AST 丛顶至下遍历,翻译成 LLVM IR中间码,LLVM IR 中间码编译过程将前端的输出作为后端的输入。Objective C代码也在这一步会进行runtime的桥接:property合成,ARC处理等。
编译器后端主要包括代码生成器、代码优化器。代码生成器将中间代码转换为目标代码,代码优化器主要是进行一些优化,列如删除多余指令,选择合适寻址方式等,如果开启了bitcode 苹果会做进一步的优化,如果有新的后端架构还是可以用这份优化过的 bitcode 去生成。优化中间代码生成输出汇编代码,把之前的.i文件转换为汇编语言,产生.s文件。
Bitcode
Bitcode是LLVM编译器的中间代码的一种编码,LLVM 将 C/C++/OC/Swift等编程语言编译成芯片平台上的汇编指令或者可执行机器指令数据。BitCode就是位于这两者之间的中间码。 由于中间码的存在,可以轻易创造新的语言,或者构造新的指令输出。Bitcode仅仅只是一个中间码不能在任何平台上运行,但是它可以转化为任何被支持的CPU架构,包括目前还没被发明的CPU架构,也就是说目前打开Bitcode功能提交一个App到应用商店,后来如果苹果新出了一款手机并且CPU也是全新设计的,在苹果后台服务器一样可以从这个App的Bitcode开始编译转化为新CPU上的可执行程序,供新手机用户下载运行这个App。
❶ 使用clang查看目标代码的生成与优化结果
clang -S -fobjc-arc -emit-llvm main.m -o main.ll
❷ 得到的的main.ll内容
; ModuleID = 'main.m'
source_filename = "main.m"
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-apple-macosx10.15.0"
%struct.__NSConstantString_tag = type { i32*, i32, i8*, i64 }
@__CFConstantStringClassReference = external global [0 x i32]
@.str = private unnamed_addr constant [8 x i16] [i16 68, i16 69, i16 66, i16 85, i16 71, i16 27169, i16 24335, i16 0], section "__TEXT,__ustring", align 2
@_unnamed_cfstring_ = private global %struct.__NSConstantString_tag { i32* getelementptr inbounds ([0 x i32], [0 x i32]* @__CFConstantStringClassReference, i32 0, i32 0), i32 2000, i8* bitcast ([8 x i16]* @.str to i8*), i64 7 }, section "__DATA,__cfstring", align 8 #0
; Function Attrs: noinline optnone ssp uwtable
define i32 @main() #1 {
%1 = alloca i32, align 4
store i32 0, i32* %1, align 4
notail call void (i8*, ...) @NSLog(i8* bitcast (%struct.__NSConstantString_tag* @_unnamed_cfstring_ to i8*))
ret i32 0
}
declare void @NSLog(i8*, ...) #2
attributes #0 = { "objc_arc_inert" }
attributes #1 = { noinline optnone ssp uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "darwin-stkchk-strong-link" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "probe-stack"="___chkstk_darwin" "stack-protector-buffer-size"="8" "target-cpu"="penryn" "target-features"="+cx16,+cx8,+fxsr,+mmx,+sahf,+sse,+sse2,+sse3,+sse4.1,+ssse3,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #2 = { "correctly-rounded-divide-sqrt-fp-math"="false" "darwin-stkchk-strong-link" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "probe-stack"="___chkstk_darwin" "stack-protector-buffer-size"="8" "target-cpu"="penryn" "target-features"="+cx16,+cx8,+fxsr,+mmx,+sahf,+sse,+sse2,+sse3,+sse4.1,+ssse3,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
!llvm.module.flags = !{!0, !1, !2, !3, !4, !5, !6, !7}
!llvm.ident = !{!8}
!0 = !{i32 2, !"SDK Version", [3 x i32] [i32 10, i32 15, i32 4]}
!1 = !{i32 1, !"Objective-C Version", i32 2}
!2 = !{i32 1, !"Objective-C Image Info Version", i32 0}
!3 = !{i32 1, !"Objective-C Image Info Section", !"__DATA,__objc_imageinfo,regular,no_dead_strip"}
!4 = !{i32 4, !"Objective-C Garbage Collection", i32 0}
!5 = !{i32 1, !"Objective-C Class Properties", i32 64}
!6 = !{i32 1, !"wchar_size", i32 4}
!7 = !{i32 7, !"PIC Level", i32 2}
!8 = !{!"Apple clang version 11.0.3 (clang-1103.0.32.62)"}
❸ 中间代码生成后,需要将LLVM代码转化为汇编语言,生成.s文件交给后面的汇编器处理
clang -S -fobjc-arc main.m -o main.s
❹ main.s汇编文件部分内容如下
.section __TEXT,__text,regular,pure_instructions
.build_version macos, 10, 15 sdk_version 10, 15, 6
.globl _main ## -- Begin function main
.p2align 4, 0x90
_main: ## @main
.cfi_startproc
## %bb.0:
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset %rbp, -16
movq %rsp, %rbp
.cfi_def_cfa_register %rbp
subq $16, %rsp
leaq L__unnamed_cfstring_(%rip), %rax
movl $0, -4(%rbp)
movq %rax, %rdi
3、LLVM编译器后端的编译过程
a、汇编
目标代码需要经过汇编器处理,把汇编语言文件转换为机器码文件,产生.o文件(object file)。
clang -fmodules -c main.m -o main.o
需要通过以下命令行查看main.o文件内容:
nm -nm main.o
内容如下:
(undefined) external _NSLog
(undefined) external ___CFConstantStringClassReference
0000000000000000 (__TEXT,__text) external _main
0000000000000028 (__TEXT,__ustring) non-external l_.str
这里可以看到_NSLog是一个是undefined external的。undefined表明在当前文件暂时找不到符号_NSLog,而external表明这个符号是外部可以访问的,对应表明文件私有的符号是non-external。
b、链接
对.o文件中的对于其他的库的引用的地方进行引用,生成最后的可执行文件,同时也包括多个.o文件进行link,生成最后的match-o可执行文件。
链接又分为静态链接和动态链接:
- 静态链接:在编译链接期间发挥作用,把目标文件和静态库一起链接形成可执行文件
- 动态链接:链接过程推迟到运行时再进行
如果多个程序都用到了一个库,那么每个程序都要将其链接到可执行文件中,超级冗余,动态链接的话,多个程序可以共享同一段代码,不需要在磁盘上存多份拷贝,但是动态链接发生在启动或运行时,增加了启动时间,造成一些性能的影响。
静态库不方便升级,必须重新编译,动态库的升级更加方便。
clang main.o -o main
这个命令行是封装完成的,内部是使用以下命令行来链接其他库的:
cc main.o -framework Foundation
生成exec的执行文件main,将其直接拖拽到终端即可执行,输出:
2020-07-22 13:51:23.622 main[73894:21427749] DEBUG模式
match-o文件里的符号表有:
U _NSLog
U ___CFConstantStringClassReference
0000000100002008 d __dyld_private
0000000100000000 T __mh_execute_header
0000000100000f50 T _main
U dyld_stub_binder
二、系统架构
MAC:Cocoa框架(Foundation框架+Application Kit(AppKit)框架
IOS:Cocoa Touch框架 (Foundation框架+UIKit框架)
IOS SDK 软件开发包:界面开发(Interface Builder)、集成开发工具(Xcode)、分析工具(Instruments)、模拟器(Simulator)、编译器

1、Cocoa Touch Layer(触摸UI层)
a、简介
CocoaTouch Layer包含创建ios应用关键的框架。该层包含的框架定义应用的外观,也提供基本的应用基础和关键的技术支持,例如多任务、触摸输入、推送通知和许多其它的高级系统服务。在开发应用时,应当第一研究该层的技术和技术看是否能够满足需要。
UIKit// 创建和管理应用程序的用户界面, 支持图形和窗口, 用户接口管理,支持文本和Web内容,通过URL scheme与其他应用的集成, Camera和图片库
Multi-Touch
Core Motion
View Hierarchy
Localization
Controls
Alerts
Web View
Image Picker
Camera
Map Kit// 为应用程序提供内嵌地图的接口
EventKit// 日历事件提醒等
Notification Center// 通知中心
Address Book// 提供访问存储核心数据库中用户联系人信息的功能
AddressBookUI// 提供一个用户界面,用于显示存储在地址簿中的联系人信息
iAd// 广告
Message UI// 处理E-mail和短信
StoreKit// 为应用程序提供消费的支持
GameKit//为游戏提供网络功能
b、Cocoa Touch Layer包含如下关键技术
AirDrop
AirDrop允许用户与附近设备共享图片、文档、urls链接以及其它种类的数据。
Text Kit
TextKit是处理文本和排版的一个全功能、高级别的类集合。使用Text Kit你能在段落、列或者页上对带有风格的文本进行布局,也能在任意区域(如图形)周围布局流动的文本,还能用它来管理多种字体。
开发应用时应该第一思考使用Text Kit来进行文本呈现,而不是Core Text。Text Kit与所有UIKit中的基于文本的控制集成允许应用更容易地创建、编辑、显示和存储文本。
UIKit Dynamics
UIKit dynamics用来为符合UIDynamicItem协议的UIView对象或其它对象规定动画行为。
Multitasking
在ios中多任务用来设计来使电池使用时间最大化。
Auto Layout
使用AutoLayout定义如何在用户接口上布局元素的规则,这些规则表达了视图类之间的关系,如规定一个按钮总是处于它的父窗口的左边缘20个点。
Storyboards
方便在一个位置看到所有的视图和视图控制器以及理解它们是如何一起工作的。故事版的一个重大的部分是定义segues(segues是从一个视图控制器到另一个的转换)。
Apple Push Notification Service
苹果的推送通知服务提供了一种提示用户关于新信息的方式,即使应用当前不在激活运行状态。使用该服务,你能推送文本通知,在应用图标上增加一个标记或者在任意时间触发声音提示。这些消息让用户知道他们应该打开应用来接收相关信息。
第一、应用必须登记该通知服务以及在通知被提交时处理相关的通知数据。
第二、你必须提供一个服务端的进程来产生通知。服务端的进程可以使用你自己的本地服务器或者使用苹果的推送通知服务。
Local Notifications
本地通知作为推送通知机制的补充,可以给应用提供一种不依赖外部服务器产生本地通知的方式。
Gesture Recognizers
手势识别用来检测一般类型的手势。为了使用它,你能在你的视图上附加手势识别功能和并给它提供一个在手势出现时要执行的方法。 手势识别跟踪原始的触摸事件和确定它们什么时候与想要的手势匹配。
c、Cocoa Touch层框架
Address Book UI Framework(地址本UI框架)
创建新的联系人和编辑和选择已存在的联系人。
Event Kit UI Framework(日历事件UI框架)
观察和编辑月历相关的事件。
Game Kit Framework(游戏工具框架)
让用户能够在线共享他们的游戏相关的信息。
iAd Framework(iAD框架)
自动处理、加载和呈现富媒体广告以及应答在那些广告条上的点击等所有相关的工作。
Map Kit Framework(地图工具框架)
除了显示一个地图,你能使用该框架接口来定制地图的内容和外观,也能使用注解来标记感兴趣的点,也能使用定制的内容来与地图内容叠置。例如,你可以在地图上来画一条公交路线,或者使用注解来高亮显示附近的商店和餐馆。
除了显示地图,MapKit框架还能与地图应用以及苹果的地图服务器集成来为用户指引方向。
地图应用能够给任意支持方向的应用提供方向的代理。如提供特定类型方向的应用,例如一个显示地铁路线的应用,能登记请求接收地图应用提供的方向。
Message UI Framework( 消息UI框架)
该框架用来在应用中提供编辑邮件和sms消息的支持。 编辑支持包括一个呈现到你的应用的视图控制器接口,并能设置这个视图控制器的一些区域,如接收人、主题、邮件主体和邮件想包括的任意附件。
UIKit Framework
该框架提供实现图形和事件驱动的应用的至关重大的基础。包括:
- 基本的应用管理,包括应用的主循环
- 用户接口管理,包括对
storyboards文件的支持 - 一个用来封装用户
UI内容的视图控制器模式 - 标准系统视图和控制对象
- 提供处理触摸和运动事件的支持
- 支持包括与
iCloud集成功能的文档模式 - 图形和窗口支持,包括支持外部显示器
- 多任务支持
- 打印支持
- 定制标准
UIKit控制的外观 - 支持文本和
web内容 - 剪切、复制、粘贴的支持
- 支持动画
UI - 通过
url和框架接口与系统提供的其它应用集成的能力 - 对有障碍用户的可存取性的支持
- 支持
ApplePush Notification服务 - 本地通知调度和提交
-
pdf创建 - 支持定制像系统键盘行为一样的用户输入视图
- 支持创建与系统键盘交互的定制的文本视图
- 支持通过
email、Twitter、Facebook和其它服务共享内容 - 也支持一些设备特定功能的集成,例如
- 内建的摄像机
- 用户的图片库
- 设备名和模式信息
- 电池状态信息
- 接近传感器信息
- 来自附件耳机的远程控制信息
2、MediaLayer(媒体层)
通过它我们可以在应用程序中使用各种媒体文件,进行音频与视频的录制,图形的绘制,以及制作基础的动画效果。
MediaPlayer// 提供播放视频和音频的功能,是个播放器
AV Foundation// 使用更多的音视频框架,对C语言的接口进行了封装
CoreAudio// 基于C语言的接口,定义核心音频的音频数据类型,能通过核心音频访问手机设备的振动功能
AudioUnit// 提供音频和流媒体文件的回放和录制,并且管理音频文件和播放提示声音
AudioToolbox// 提供使用内置音频单元服务,音频处理模块
OpenAL// 开放音频库,跨平台的标准,能传递位置音频
Core Animation// 图形动画处理框架
QuartzCore// 包含CoreAnimation接口,提供动画特效以及通过硬件进行渲染的能力
Quartz 2D// 贝塞尔曲线、变换、渐变
Core Graphic// 包含了Quartz 2D画图API,提供2D绘制的基于C的API,支持pdf文档创建
OpenGL ES// 提供简洁而高效的绘制2D和3D图形的OpenGL API子集,为全屏游戏类应用提供高帧率
Core Image// 人脸识别和滤镜
Core Text// 文本
Image IO// 导入导出图像
a、图形技术
UIKit graphics
-
UIKit定义的绘制图像和Bezier路径,以及动画视图内容的高级别技术 -
UIKit视图提供快速和有效的方式来呈现图像和文本内容。 -
UIKit视图也能通过显示和使用UIKit dynamics技术进行动画
CoreGraphics.framework
CoreGraphics 框架包含Quartz 2D绘制api。 Quartz是一个原先用在OS X的先进的、向量绘制引擎。Quartz支持路径绘制,抗锯齿呈现,剃度,图像,颜色,坐标空间转换以及pdf 内容创建、显示和分析等功能。 虽然这个api是C-based接口,但它使用了面向对象抽象来表现基本的绘制对象,因此使它容易存储和重用图形内容。
CoreAnimation框架
CoreAnimation也是Quartz核心框架的一部分,是优化应用动画体验的基础技术。 UIKit视图基于 Core Animation提供视图级别的动画支持。当你想对动画行为有更多控制时也能直接使用CoreAnimation。
CoreImage.framework
CoreImage 框架提供一组强劲的内建过滤器来操作视频和静态图像。 你能在触摸弹起、纠正图片以及面部和特征检测等许多方面使用这些内建的过滤器。这些过滤器的先进特点是它们操作是非破坏方式,即原先的图像不被改变。
OpenGL ES 框架
OpenGL ES 框架 (OpenGLES.framework)提供绘制2d和3d内容的工具, 它是一个C-based的框架。 该框架以最接近设备硬件的方式为全屏沉浸式应用例如游戏提供细粒度的图形控制和高的帧率。你能够与EAGL配合使用这个框架,为OpenGL ES 绘制调用和UIKit的本地窗口对象之间提供接口。 该框架支持OpenGL ES 1.1、 2.0、 3.0规范。2.0规范增加了片段和顶点着色的支持,3.0规范增加了更多的功能,包括多个呈现目标和变换反馈。
CoreText.framework
CoreText框架提供一个对文本进行布局和字体处理的简单的、高性能的C-based接口。 该框架用在不使用TextKit但仍想获得文字处理应用中。 该框架提供了一个智能的文本布局引擎,包括在其内容周围环绕文本的能力,它也支持使用多种字体和呈现属性的先进的文本风格。
ImageIO.framework
ImageI/O 框架提供输入和输出图像数据和图像元数据的接口。 该框架利用CoreGraphics数据类型和功能,并支持在ios 上所有的可获得的标准的图像类型。你能使用这个框架存取Exif和IPTC元数据属性。
Assets Library 框架
AssetsLibrary 框架(AssetsLibrary.framework)提供对用户设备上图片应用管理的图片和视频的存取。 使用该框架来存取用户保存的图片相册或导入到设备的任意相册中的图片,你也能保存新的图片和视频到用户的图片相册。
GLKit.framework
-
GLKit框架包含一组简化创建OpenGL ES应用的Objective-C based单元类 -
GLKView和GLKViewController类提供一个OpenGL ES视图和其呈现循环的标准实现 -
OpenGL ES视图代表应用管理底层的frame buffer对象,应用只需在视图上绘制 -
GLKTextureLoader类提供在你的应用中使用图像转换和加载线程,允许应用自动加载纹理图像到应用的上下文。 能够异步或同步加载纹理。当异步加载纹理时,应用应提供一个完成处理块,该处理块在纹理加载进应用上下文时被调用 -
GLKit框架提供向量、矩阵和3d 旋转以及提供OpenGL ES上的矩阵 -
GLKBaseEffect、GLKSkyboxEffect和GLKReflectionMapEffect类实现给通用图形操作提供可配置的图形着色。尤其GLKBaseEffect类实现了OpenGL ES规范上的光亮和材质模式
QuartzCore.framework
QuartzCore 框架包含Core Animation。Core Animation是一个先进的复合技术,使用它能容易创建快和有效的view-based的动画。 复合引擎利用底层硬件来有效的实时操作视图内容。只需规定动画的起始点,CoreAnimation做剩下的工作。由于Core Animation内嵌在UIView架构的底层,因此它总是可用的。
b、声音技术
Media Player framework
该框架是一个高级别的框架, 用来为用户提供对iTunes库存取的容易方式,也提供对播放轨迹和播放列表的支持。当你想快速在应用中集成声音以及不需要控制播放行为时可以使用该框架。
AV Foundation
AVFoundation是管理声音以及视频播放和记录的面向对象接口。在记录声音和想对声音播放过程有更好的控制时可以使用该框架。
OpenAL 框架
OpenAudio Library (OpenAL)接口是用来在应用中提供位置音效的跨平台的标准。能够使用该接口在游戏和其它需要位置音效输出的程序中实现高性能、高质量的声音。 由于OpenAL是跨平台的标准,在iOS使用OpenAL编写的代码能够容易地移植到许多其它平台。
CoreAudio.framework
Core Audio框架是一个对声音处理提供本地支持的框架家族。这些框架支持声音的产生、记录、混合和回放。你也能使用这些接口处理MIDI内容以及串流声音和MIDI内容到其它应用。
AudioToolbox.framework
AudioToolbox框架提供声音文件和声音流的播放和记录服务,也提供管理声音文件,播放系统警告声音,在某些设备上触发震动的支持。
AudioUnit.framework
提供使用内建声音单元,也提供使你的应用的声音内容作为对其它应用可视的声音组件的支持。
CoreMIDI.framework
提供与MIDI设备通讯的标准方式,包括硬件键盘和合成器。你使用这个框架来发送和接收MIDI消息以及与通过dock连接器或网络连接到IOS设备的MIDI外设交互。
MediaToolbox.framework
提供对声音tap接口的存取。
c、视频技术
UIImagePickerController
UIImagePickerController是一个选择用户媒体文件的UIKit视图控制器。
Media Player
MediaPlayer框架提供一组呈现视频内容的简单易用的接口,该框架支持全屏和小窗口视频播放,也为用户提供可选的播放控制。
AV Foundation 框架
AVFoundation 框架 (AVFoundation.framework)提供一组播放、记录和管理声音和视频内容的Objective-C类。当你想在应用的UI接口无缝集成媒体能力时使用该框架。你也能使用它来进行更先进的媒体处理,例如同时播放多个声音或者控制播放和记录过程的多个方面。
该框架提供的服务包括:
- 声音会话管理,包括对系统声明你的应用声音
- 对应用媒体资源的管理
- 对编辑媒体内容的支持
- 捕捉声音和视频的能力
- 播放声音和视频的能力
- 轨迹管理
- 媒体元数据的管理
- 立体拍摄
- 声音之间的准确同步
- 提供一个确定声音文件细节内容的
Objective-C接口,例如数据格式,采样率,通道数 - 通过
AirPlay串流内容
CoreMedia
CoreMedia框架为操作媒体定义低级别的数据类型和接口。 当你需要对视频内容有严格要求的控制时可以使用该框架。
AirPlay
AirPlay让应用串流声音和视频内容到Apple TV或者串流声音内容到第三方扬声器和接收器。 AirPlay内建于许多框架,包括UIKit、Media Player、AVFoundation、Core Audio。因此在大多数情况你不需要为了支持它做任何事。在使用那些框架时,当播放内容时自动获得AirPlay支持。当用户选择使用AirPlay播放内容时系统自动进行路由。
MediaAccessibility.framework
MediaAccessibility 框架管理媒体文件中closed-caption内容的呈现。 该框架与新的设置配合工作可以让用户决定是否允许closed-caption显示。
MediaPlayer.framework
- 播放视频到用户屏幕或通过
AirPlay到另外的设备屏幕。能够全屏幕播放视频或以可改变视图大小的方式播放 - 存取用户的
iTunes音乐库。能够播放音乐轨迹和播放列表、搜索音乐、给用户提供一个媒体picker呈现接口 - 配置和管理电影的回放
- 在锁定屏幕和app 切换窗口上显示
NowPlaying信息。当内容通过AirPlay提交时还能显示到AppleTV上 - 检测视频通过
AirPlay被串流的时间
d、游戏技术
Game Controller 框架
GameController 框架 (GameController.framework)让你在应用中发现和配置针对iPhone/iPod/iPad设备的游戏控制器。 游戏控制器可以是物理连接到iOS设备或者是通过蓝牙无线连接。GameController框架当控制器可获得时通知你的应用让应用可以规定哪个控制器输入与你的应用相关。
SpriteKit.framework
SpriteKit 框架为2d和2.5d游戏提供硬件加速的动画系统。 SpriteKit提供大多数游戏需要的基础,包括一个图形引擎和动画系统,声音播放支持,一个物理仿真引擎。 使用SpriteKit不需你自己创建这些事情,使你聚焦在内容设计和内容的高级别的交互上。
在Sprite Kit应用中内容组织为场景。一个场景包括纹理对象,视频,路径图形,核心图像过滤器和其它的特效。SpriteKit利用这些对象,确定这些对象到屏幕上的最有效的方式。当在场景中到了动画内容的时刻,你能使用SpriteKit来显式规定你想执行的行动或使用物理仿真引擎来为那些对象定义物理行为(例如重力、引力或排斥力)。
除了SpriteKit框架,也有其它Xcode工具来创建颗粒发射效果和纹理图。你能使用Xcode工具来管理应用资源和快速地更新Sprite Kit场景。
3、CoreServices Layer(核心服务层)
a、简介
CoreServices Layer包含应用需要的基础的系统服务。这些服务中的核心是CoreFoundation和Foundation框架,定义了所有应用使用的基本类型。该层也包含独立的技术来支持一些其它功能, 例如位置、iCloud、社交媒体和网络。
Foundation// 提供Object-C的基础类(像NSObject)、基本数据类型和操作系统服务等
CoreFoundation// 基于C语言的接口集,提供常用数据类型,如Unicode strings、XML、URL等
Core Data// 数据存储
SQLite// 基于C语言的小型数据库
File Access// 文件访问
Preferences// 偏好设置
Core Location// 利用附近的GPS、蜂窝基站或Wi-Fi信号信息测量用户的当前位置
Core Motion(重力加速度,陀螺仪)
CFNetwork// 可以访问低层的结构BSD Sockets,利用SSL或TLS创建加密连接,解析HTTP协议,鉴别HTTP和HTTPS服务器,在FTP服务器工作,发布、解析和浏览Bonjour服务
Webkit// 浏览器引擎
JavaScriptCore// JavaScript引擎
Threading// 多线程
b、iCloud Storage(云存储)
iCloud存储让应用把用户文档和数据写到一个中心位置,然后用户能从他们的计算机和ios 设备存取这些数据。使用iCloud可以使用户文档无所不在,意味着用户能从任何设备阅读或编辑那些文档,而不需要显式的同步或文件传输。存储文档到用户的iCloud账户也为用户提供了一层安全。即使用户的设备丢失,那些设备上的文档如果已经保存到iCloud就不会丢失。
iCloud文档存储
可以使用这个功能在用户的iCloud账户存储用户文档和数据。大多数应用使用iCloud文档存储来共享来自用户账户的文档。使用iCloud文档存储用户关心的是文档能否能够在设备之间共享以及他们是否能够从一个给定设备查看和管理那些文档。
iCloud键值存储
使用这个功能在应用之间共享数据。iCloud键值存储是应用之间共享小量数据(几十k字节)。应用应当用它存储非紧急的应用数据,例如设置。
Automatic Reference Counting(自动引用计数)
自动引用计数是一个编译级别的功能,用它来简化Objective-C对象生命周期过程的管理,以此取代用户必须记住什么时候应该保持和释放对象。ARC评估对象的生命周期需求和自动在编译时间插入适当的方法调用。
Block Objects(块对象)
- 作为代理或代理方法的取代
- 作为回调功能的取代
- 为某个一次性操作实现其完成处理函数
- 在一个集合中的所有项上执行一个任务
- 与提交队列一起执行异步任务
Data Protection(数据保护)
数据保护允许应用利用设备上已有的内建的加密方法来使用用户的敏感数据。 当应用指定一个特定的文件被保护时,系统在磁盘上以加密格式存储该文件。当设备锁定时,该文件的内容不能被应用和任何潜在的侵入者存取。可是当设备由用户解锁时,一个解密key被创建允许你的应用存取那个文件。
用户也可以使用其它级别的数据保护机制。实现数据保护需要你思考如何创建和管理你想保护的数据。应用必须设计在数据的创建时间加密数据,以及当用户锁定或解锁设备时为存取条件改变做好准备。
File-Sharing Support(文件共享支持)
文件共享支持使用户数据文件在iTunes可被其它应用获得。一个应用声明支持文件共享使它的/Documents目录下的内容允许其它用户获得。当用户需要时能够把文件从iTunes移进或移出应用的Documents目录。
Grand Central Dispatch
GCD是一个BSD技术,应用可以用来管理其任务的执行。 GCD与高优化的核组合成一个异步编程模式,来提供方便和更有效的对线程的替代。GCD也为许多低级别的任务提供一个方便的选择,例如读和写文件描述符,实现定时器和监视信号和处理事件。
In-App Purchase(应用内购买)
应用内购买提供在应用中销售应用特定的内容和服务以及来自iTunes的内容的能力。 这个功能使用StoreKit框架实现,并提供使用用户的iTunes账号来处理金融方面的事务需要的基础。应用处理全部用户体验和供购买的内容及可获得服务的呈现。作为可下载的内容,你能把可下载的内容放到你自己的服务器或使用苹果的服务器。
SQLite
SQLite库让你在你的应用中嵌入一个轻量级的sql数据库,而不需要运行一个分离的远程数据库服务进程。从你的应用,你能创建本地数据库文件,管理数据库表和表中的数据记录。 SQLite库为通用功能使用设计,但已经被优化来提供对数据记录更快速的存取。
XML Support
Foundation框架提供一个NSXMLParser类用来从一个xml文档中引出元素。 操作xml内容的额外的支持由libxml2库提供支持。libxml2开源库让你快速地分析或写任意的xml数据和转换xml内容到html。
c、通讯录框架
Accounts Framework(帐户框架)
Accounts框架 (Accounts.framework)为确定的用户账号提供单点登录模式。 单点登录通过消除用户分离的多个账号需要的多次登录提示,来增强用户体验。它也通过为应用管理账号认证过程来简化开发模式。 该框架需要与Social框架配合使用。
Address Book Framework(地址本框架)
AddressBook 框架(AddressBook.framework)提供可编程存取用户的联系人数据库的方式。 如果应用使用联系人信息,你能使用该框架来存取和修改联系人信息。例如一个聊天应用可以使用该框架来引出可能的联系人列表,通过联系人列表来启动一个会话以及在特定视图显示那些联系人。
重大提示:存取用户的联系人数据需要用户的明确的许可。应用因此必须准备好用户拒绝存取的情形。应用也鼓励提供Info.plist键来描述需要存取的缘由。
d、网络与广告框架
Ad Support Framework(广告支持框架)
AdSupport 框架 (AdSupport.framework)提供存取应用用于广告功能的一个标识。 该框架也提供一个指示用户是否选择广告跟踪的标志。应用在尝试存取广告标识前需要判断这个标志。
CFNetwork 框架
CFNetwork框架 (CFNetwork.framework)是高性能的使用面向对象对网络协议进行抽象的一组C-based接口。这些抽象提供对协议栈细节的控制,使它容易使用低级别的构造例如BSDsockets。 你能使用该框架简化与ftp或http服务器通讯或决定dns hosts的任务。使用CFNetwork框架,你能:
- 基于
BSD sockets - 使用
SSL或TLS创建安全连接 - 决定
dns hosts - 认证
HTTP服务器、与HTTP服务器或者HTTPS服务器交互 - 与
FTP服务器交互 - 发布、解决和浏览
Bonjour服务
e、Core Data 框架
CoreData 框架 (CoreData.framework)框架是管理MVC应用中的数据模式的一种技术。 CoreData框架打算在数据模式是高结构化的应用中使用。取代编程定义数据结构,在xcode中能够使用图形工具来建立一个表现你的数据模式的纲要。在运行时,你的数据模式实体的实例通过CoreData框架被创建、管理和获得。 通过为你的应用管理其数据模式,CoreData大大减少了必须书写的代码量。
- 为优化性能在
SQLite数据库中存储对象数据 - 一个管理数据表视图结果的
NSFetchedResultsController类 - 对基本的文本编辑之外的
undo/redo的管理 - 支持属性值的校验
- 支持传播改变确保对象之间的关系保持一致性
- 支持分组、过滤和在内存中优化数据
f、Core Foundation 框架
- 集合数据类型(数组、集合等)
- 应用打包
Bundles - 字符串管理
- 日期和时间管理
- 原始数据块管理
-
Preferences管理 -
URL和流操作 - 线程
- 端口和
socket通讯
CoreFoundation 框架 (CoreFoundation.framework)是一组C-based接口,为ios应用提供基本的数据管理和服务功能。CoreFoundation框架与Foundation框架紧密相关,为一样的基本功能提供Objective-C接口。当你需要混合使用Foundation对象和Core Foundation类型时,你能利用两个框架之间存在的“toll-free bridging”。toll-free bridging意味着你能可交换地在两个框架的方法和功能中使用一些CoreFoundation和Foundation类型。这个支持对许多数据类型可用,包括集合和字符串数据类型。每个框架的类和类型描述声明一个对象是否是toll-free bridged以及在是的情况下来标识它连接到什么对象。
g、Core Location 核心位置框架
CoreLocation 框架 (CoreLocation.framework)为应用提供位置信息。该框架使用GPS、蜂窝、或者Wi-Fi来定位用户的当前经度和纬度。 你可在你的应用中集成该技术为用户提供位置信息。例如,你可实现一个基于用户的当前位置搜索附近餐馆、商店或者银行的应用。
- 在包括磁力计的ios设备上存取罗盘信息
- 基于地理位置或蓝牙
beacon进行区域监视 - 支持使用蜂窝基站的低耗电的位置监视
- 与
MapKit配合来增强在特定情景下的位置数据的质量,例如开车时
h、媒体、运动框架
Core Media Framework(核心媒体框架)
CoreMedia 框架(CoreMedia.framework)提供由AV Foundation框架使用的低级别的媒体类型。大多数应用从不需要使用该框架,但少数需要更准确控制音视频内容创建和呈现的开发者可以使用它。
Core Motion Framework (核心运动框架)
CoreMotion 框架 (CoreMotion.framework)提供一组接口来存取设备上可获得的运动数据。 该框架支持使用一组新的block-based接口来存取原始和加工过的加速度计数据。对于带有陀螺仪的设备,你也能获得原始的陀螺仪数据和加工过的反应设备方向和旋转速度的数据。你能在游戏或其它使用运动作为输入或作为增强用户体验的方式的应用中使用加速度计和陀螺仪两种数据。对于带有计步硬件的设备,你能存取它的数据来跟踪健康相关的运动。
i、电话、日历框架
Core Telephony Framework(核心电话框架)
CoreTelephony 框架 (CoreTelephony.framework)提供与蜂窝电话的通话相关的信息交互的接口。 可以使用该框架来获得用户的蜂窝服务提供者的信息。对于对蜂窝call事件感兴趣的应用例如VoIP应用也能在那些事件出现时被通知。
Event Kit 框架
- 获得用户月历上存在的事件和提示
- 增加事件到用户月历
- 为用户创建提示和使它们出目前提示应用中
- 为月历事件配置提示信号,包括设置提示信号应该什么时候触发的规则
EventKit 框架 (EventKit.framework)提供存取用户设备上的月历事件的接口。存取用户的月历和提示数据需要用户的明确许可。应用因此必须准备好用户拒绝的情形,也鼓励应用在其Info.plist文件中提供一个描述需要存取缘由的键。
j、Foundation框架
Foundation框架 (Foundation.framework)提供Core Foundation框架提供的许多功能的Objective-C封装。
- 集合数据类型(数组、集合等)
- 应用打包
Bundles - 字符串管理
- 日期和时间管理
- 原始数据块管理
-
Preferences管理 -
URL和流操作 - 线程和运行循环
Bonjour- 通讯端口管理
- 国际化
- 规则表达式匹配
-
Cache支持
k、脚本、标识符、附近设备框架
JavaScript 核心框架
JavaScriptCore 框架 (JavaScriptCore.framework)为许多标准的JavaScript对象提供Objective-C语言的封装。使用该框架来执行JavaScript代码和分析JSON数据。
Mobile Core Services (移动核心服务框架)
MobileCore Services 框架(MobileCoreServices.framework)定义在通用类型标识符(UTIs)中使用的低级别类型。
Multipeer Connectivity Framework(多方连接框架)
MultipeerConnectivity 框架 (MultipeerConnectivity.framework)支持附近设备的发现,并与那些设备直接通讯(不需要Internet连接)。 使用该框架能够与附近设备通讯、容易的创建多人会话、支持可靠地传输顺序和实时数据。 该框架为发现和管理网络服务提供可编程和UI-based的选项。应用能在ui中集成MCBrowserViewController类来显示一个发现设备列表让用户选择。另外也能使用MCNearbyServiceBrowser类来可编程的查找和管理对方设备。
l、杂志、卡片框架
Newsstand Kit 框架
Newsstand应用为用户提供了一个阅读杂志和报纸的位置。想通过Newsstand提供杂志和报纸内容的出版商能够使用NewsstandKit 框架(NewsstandKit.framework)创建它们自己的iOS应用,让用户启动新杂志和报纸新闻的后台下载。在启动下载后,系统处理下载操作和当内容可获得时通知应用。
Pass Kit 框架
Passbook应用为用户提供了一个存储订货单、登机卡、入场券和商业折扣卡的位置。取代物理携带这些东西,用户目前能在IOS设备上存储它们,并和过去一样的方式使用。 Pass Kit 框架 (PassKit.framework)提供把这些功能集成到你的应用的Objective-C接口。 你能与web接口和文件格式信息组合使用该框架来创建和管理你们公司提供的电子入场券。
电子入场券由你们公司的web service创建并通过email、Safari或定制的应用提交到用户的设备。电子入场券本身使用特殊的文件格式,在提交之前被加密签名。文件格式标识关于提供服务的相关信息以及用户知道是什么服务的信息。 电子入场券也可以包含一个对卡进行校验的条码或其它信息,以便它能被兑换或使用。
m、预览、浏览器、分享框架
Quick Look 框架
QuickLook框架(QuickLook.framework)提供了一个预览应用文件内容的接口。 该框架主要打算用于应用从网络下载文件或处理来自不知道来源的文件的工作。 在得到文件后,你能使用该框架提供的视图控制器来直接显示文件的内容。
Safari Services 框架
SafariServices 框架 (SafariServices.framework)提供以可编程的方式增加URLs到用户的Safari的书签的支持。
Social Framework(社交框架)
Social框架(Social.framework)提供一个简单的接口来存取用户的社交媒体账号。 该框架取代Twitter框架并增加了其它社交账号,包括Facebook、微博以及其它。 应用能使用该框架提交状态更新和图像到用户账号。该框架与Accounts框架一起为用户提供单点登录并确保存取的用户账号是经过准许的。
n、商店、系统配置框架
Store Kit 框架
StoreKit 框架 (StoreKit.framework)提供在ios应用中购买内容和服务的支持,也被称作应用内购买。 例如,你能使用该功能来允许用户去锁另外的应用功能。或者如果你是一名游戏开发者,你能使用它来提供另外的游戏级别。在这两种情况,StoreKit框架处理事务的收入方面事务,包括通过用户的iTunes账号处理付费请求,给应用提供关于购买的信息。
Store Kit聚集在事务的金融方面,确保事务正确和安全。你的应用处理事务的其它方面,包括购买接口的呈现和适当内容的下载。 工作的分工让你能够控制购买内容的用户体验。由你决定你想呈现给用户什么样的购买接口和什么时候那样做,你也决定你的应用最好的提交机制。
System Configuration Framework(系统配置框架)
SystemConfiguration 框架(SystemConfiguration.framework)提供可达性接口,你能用它来确定设备的网络配置,也能使用该框架确定一个Wi-Fi或蜂窝连接是否在用以及一个特定的主机服务器是否能够存取。
4、Core OS(核心操作系统层)
a、简介
为上层结构提供最基础的服务如操作系统内核服务(BSD sockets、I/O访问、内存申请、文件系统、数学计算等)等。它可以直接和硬件设备进行交互。包括以下部分:
本地认证,包括指纹识别验证等
Security// 提供管理证书(Certificates),公钥和私钥信任策略,keychain、hash认证数字签名等与安全相关的解决方案
File System// 文件系统访问
CoreBluetooth// 利用蓝牙和外设交互,包括扫描连接蓝牙设备,保存连接状态,断开连接,获取外设的数据或者给外设传输数据等等
BSD Sockets// 网络
Bonjour和DNS服务
OS X Kernel Mach// 线程
标准I/O
Power// 电量
内存分配
SystemConfiguration// 检测当前网络是否可用和硬件设备状态的能力
Accelerate// 加速器框架, 执行数学、大数字以及DSP运算,这些接口iOS设备硬件相匹配
b、System 高级功能
System包含kernel环境、驱动以及操作系统级别的unix接口。kernel本身负责操作系统的每一个方面:如虚拟内存管理、线程、文件系统、网络和互联通信。在该层的驱动也提供在可获得的硬件与系统框架之间的接口。为了安全,对kernel和驱动的存取被限制到一组有限的系统框架和应用。 IOS提供一组存取许多操作系统低级别功能的接口。应用通过LibSystem库存取这些功能。该C based的接口提供如下功能的支持。
- 多任务(
POSIX线程和GCD) - 网络(
BSDsockets) - 文件系统存取
- 标准
I/O -
Bonjour和DNS服务 - 位置信息
- 内存分配
- 数学计算
c、Accelerate 加速框架
Accelerate框架 (Accelerate.framework)包含执行数字信号处理、线性代数、图像处理计算的接口。 使用该框架的优点是它们针对所有的ios设备上存在的硬件配置做了优化,因此你能写一次代码确保在所有设备上有效运行。
d、Core Bluetooth Framework(核心蓝牙框架)
CoreBluetooth 框架 (CoreBluetooth.framework)允许开发者与蓝牙低耗电外设(LE)交互。
- 扫描蓝牙外设,连接和断开发现的蓝牙外设
- 声明应用的服务,转换 ios 设备成其它蓝牙设备的外设
- 从IOS设备广播
iBeacon信息 - 保存你的蓝牙连接的状态,当应用重新启动时恢复那些连接
- 蓝牙外设可获得性变化时获得通知
e、Security Framework(安全框架)
除了内建的安全功能,IOS也提供了一个明确的安全框架(Security.framework),你能用它来保证应用管理的数据的安全。 该框架提供管理证书、公有和私有key和信任策略的接口。支持产生加密安全伪随机码。它也支持在keychain(保存敏感用户数据的安全仓库)中保存证书和加密key。
公共加密库提供对称加密、hash认证编码(HMACs)、数字签名等额外支持,数字签名功能本质上与iOS上没有的OpenSSL库兼容。
在你创建的多个应用之间共享keychain是可能的。共享使它容易在一样的一套应用之间更平滑的协作。例如,你能使用该功能来共享用户口令或其它元素,否则可能使每个应用都需要提示用户。 为了在应用之间共享数据,必须为每个应用的Xcode工程配置适当的权限。
f、External Accessory Framework(外部附件框架)
ExternalAccessory框架(ExternalAccessory.framework)提供与连接到IOS设备的硬件附件通讯的支持。 附件能通过30-pin连接器或使用蓝牙无线与IOS设备进行连接。该框架给你提供了获得关于每一个可获得的附件信息和启动通讯会话的方式。然后,你可自由的使用附件支持的命令直接操作附件。
g、Generic Security Services Framework(通用安全服务框架)
GenericSecurity Services框架 (GSS.framework)给ios应用提供一组标准安全相关的服务。该框架的基本接口规定在IETFRFC2743 and RFC4401。除了提供标准的接口,IOS还包括一些没有在标准中规定但被许多应用需要的一些管理证书需要的额外东西。




















暂无评论内容