本文次要介绍
1.Clang与LLVM
2.GDB与LLDB
3.homebrew与CocoaPods等
4.iOS零碎框架
1.Clang与LLVM
LLVM我的项目的倒退起源于2000年伊利诺伊大学厄巴纳-香槟分校维克拉姆·艾夫(Vikram Adve)与克里斯·拉特纳(Chris Lattner)的钻研,他们想要为所有动态及动静语言发明出动静的编译技术。LLVM是以BSD受权来倒退的开源软件。2005年,苹果电脑雇用了克里斯·拉特纳及他的团队为苹果电脑开发应用程序零碎,LLVM为现今Mac OS X及iOS开发工具的一部分。
LLVM的命名最早源自于底层虚拟机(Low Level Virtual Machine)的首字母缩写,因为这个我的项目的范畴并不局限于创立一个虚拟机,这个缩写导致了宽泛的纳闷。LLVM开始成长之后,成为泛滥编译工具及低级工具技术的统称,使得这个名字变得更不贴切,开发者因此决定放弃这个缩写的意涵,现今LLVM已单纯成为一个品牌,实用于LLVM下的所有我的项目,蕴含LLVM中介码(LLVM IR)、LLVM除错工具、LLVM C++规范库等。
Xcode3之前,用的是GCCXcode3,GCC依然保留,然而也推出了LLVM,苹果举荐LLVM-GCC混合编译器,但还不是默认编译器Xcode4,LLVM-GCC成为默认编译器,但GCC仍保留Xcode4.2,LLVM3.0成为默认编译器,纯用GCC不复可能Xcode4.6,LLVM降级到4.2版本Xcode5,LLVM-GCC被遗弃,新的编译器是LLVM5.0,从GCC过渡到LLVM的时代正式实现
Clang - a C language family frontend for LLVM
Clang(发音为/klæŋ/) 是一个C、C++、Objective-C和Objective-C++编程语言的编译器前端。它采纳了底层虚拟机(LLVM)作为其后端。它的指标是提供一个GNU编译器套装(GCC)的替代品。作者是克里斯·拉特纳,在苹果公司的资助反对下进行开发,而源代码受权是应用类BSD的伊利诺伊大学厄巴纳-香槟分校开源码许可。
Clang我的项目包含Clang前端和Clang动态分析器等。
Clang的在出世之前就曾经明确了他的使命——干掉该死的GCC。有了LLVM+Clang,从此,苹果的开发风貌面目一新。从此解脱了GCC的限度。主观的说GCC是有很多的长处,例如反对多平台,很风行,基于C无需C++编译器即可编译。这些长处到苹果那就可能是毛病了,苹果须要的是——快。这正是Clang的长处,除了快,它还有与GCC兼容,内存占用小,诊断信息可读性强,易扩大,易于IDE集成等等长处。有个测试数据:Clang编译Objective-C代码时速度为GCC的3倍。
iOS编译过程
Objective-C与swift都采纳Clang作为编译器前端,编译器前端次要进行语法分析,语义剖析,生成中间代码,在这个过程中,会进行类型查看,如果发现错误或者正告会标注进去在哪一行。
编译器后端会进行机器无关的代码优化,生成机器语言,并且进行机器相干的代码优化,依据不同的零碎架构生成不同的机器码。
C++,Objective C都是编译语言。编译语言在执行的时候,必须先通过编译器生成机器码。
如上图所示,在xcode按下cmd+B之后的工作流程。
预处理(Pre-process):他的次要工作就是将宏替换,删除正文开展头文件,生成.i文件。
词法剖析 (Lexical Analysis):将代码切成一个个 token,比方大小括号,等于号还有字符串等。是计算机科学中将字符序列转换为标记序列的过程。
语法分析(Semantic Analysis):验证语法是否正确,而后将所有节点组成形象语法树 AST 。由 Clang 中 Parser 和 Sema 配合实现
动态剖析(Static Analysis):应用它来示意用于剖析源代码以便主动发现错误。
两头代码生成(Code Generation):开始IR中间代码的生成了,CodeGen 会负责将语法树自顶向下遍历逐渐翻译成 LLVM IR,IR 是编译过程的前端的输入后端的输出。
优化(Optimize):LLVM 会去做些优化工作,在 Xcode 的编译设置里也能够设置优化级别-01,-03,-0s,还能够写些本人的 Pass,官网有比拟残缺的 Pass 教程: Writing an LLVM Pass — LLVM 5 documentation 。如果开启了 bitcode 苹果会做进一步的优化,有新的后端架构还是能够用这份优化过的 bitcode 去生成。
生成指标文件(Assemble):生成Target相干Object(Mach-o)
链接(Link):生成 Executable 可执行文件
通过这一步步,咱们用各种高级语言编写的代码就转换成了机器能够看懂能够执行的指标代码了。
环境搭建
cd /optsudo mkdir llvmsudo chown `whoami` llvmcd llvmexport LLVM_HOME=`pwd`git clone -b release_39 git@github.com:llvm-mirror/llvm.git llvmgit clone -b release_39 git@github.com:llvm-mirror/clang.git llvm/tools/clanggit clone -b release_39 git@github.com:llvm-mirror/clang-tools-extra.git llvm/tools/clang/tools/extragit clone -b release_39 git@github.com:llvm-mirror/compiler-rt.git llvm/projects/compiler-rtmkdir llvm_buildcd llvm_buildcmake ../llvm -DCMAKE_BUILD_TYPE:STRING=Releasemake -j`sysctl -n hw.logicalcpu`
文件很多很大,须要下载一段时间
Clang Static Analyzer动态代码剖析
clang 动态剖析是通过建设剖析引擎和 checkers 所组成的架构,这部分性能能够通过 clang —analyze 命令形式调用。
命令行执行
通过clang -cc1 -analyzer-checker-help
能够列出能调用的 checker,但这些checker并不是所有都是默认开启的
这里应用一个默认敞开的checker-alpha.security.ArrayBoundV2作为例子进行操作
$ clang -cc1 -analyzer-checker-help alpha.core.BoolAssignment Warn about assigning non-{0,1} values to Boolean variables alpha.core.CastSize Check when casting a malloced type T, whether the size is a multiple of the size of T alpha.core.CastToStruct Check for cast from non-struct pointer to struct pointer alpha.core.FixedAddr Check for assignment of a fixed address to a pointer alpha.core.IdenticalExpr Warn about unintended use of identical expressions in operators alpha.core.PointerArithm Check for pointer arithmetic on locations other than array elements alpha.core.PointerSub Check for pointer subtractions on two pointers pointing to different memory chunks alpha.core.SizeofPtr Warn about unintended use of sizeof() on pointer expressions alpha.cplusplus.NewDeleteLeaks Check for memory leaks. Traces memory managed by new/delete. alpha.cplusplus.VirtualCall Check virtual function calls during construction or destruction ... alpha.security.ArrayBound Warn about buffer overflows (older checker) alpha.security.ArrayBoundV2 Warn about buffer overflows (newer checker) alpha.security.MallocOverflow Check for overflows in the arguments to malloc() alpha.security.ReturnPtrRange Check for an out-of-bound pointer being returned to callers ... core.CallAndMessage Check for logical errors for function calls and Objective-C message expressions (e.g., uninitialized arguments, null function pointers) core.DivideZero Check for division by zero core.DynamicTypePropagation Generate dynamic type information core.NonNullParamChecker Check for null pointers passed as arguments to a function whose arguments are references or marked with the 'nonnull' attribute core.NullDereference Check for dereferences of null pointers core.StackAddressEscape Check that addresses to stack memory do not escape the function ... unix.API Check calls to various UNIX/Posix functions unix.Malloc Check for memory leaks, double free, and use-after-free problems. Traces memory managed by malloc()/free(). unix.MallocSizeof Check for dubious malloc arguments involving sizeof unix.MismatchedDeallocator Check for mismatched deallocators. unix.cstring.BadSizeArg Check the size argument passed into C string functions for common erroneous patterns unix.cstring.NullArg Check for null pointers being passed as arguments to C string functions
能够应用 -enable-checker 和 -disable-checker 开启和禁用具体的 checker 或者 某种类别的 checker。
$ scan-build -enable-checker alpha.security.ArrayBoundV2 ... # 启用数组边界查看
当然,应用scan-build
启用的checker
只实用于应用scan-build
生成的html报告。scan-build
在编译装置 llvm/clang 之后能够在/llvm/tools/clang/tools/scan-build
目录下找到
//容许未被默认容许的check并进行代码剖析并将输入后果输入至网页./scan-build -enable-checker alpha.security.ArrayBoundV2 --use-analyzer=/opt/llvm/llvm_build/bin -V xcodebuild -project /Users/yuhao/TestClang/TestClang.xcodeproj -sdk iphonesimulator10.3
咱们在TestClang.xcodeproj的main.m文件中插入一段数组越界的代码
int main(){ @autoreleasepool { int a[2]; int i; for (i = 0; i < 3; i++){ a[i] = 0; } } return 0;}
而后执行下面的命令,会导出这样的一个界面
查看报表
https://upload-images.jianshu...
报表中提醒了该代码有数组越界的问题。
Xcode执行
Xcode自身曾经自带了动态检测的性能,能够通过Product-Analyze来执行动态检测,这也只是用自带的clang去执行,如果想用其余的版本,比方本人编译clang,就须要通过命令来设置。
在Xcode的Product选项卡下有Analyze的选项,Xcode中默认提供了一些checkers。
Usage: set-xcode-analyzer [options]Options: -h, --help show this help message and exit --use-checker-build=PATH Use the Clang located at the provided absolute path, e.g. /Users/foo/checker-1 --use-xcode-clang Use the Clang bundled with Xcode
能够看到,它有2个选项,
--use-checker-build
:用于将xcode的clang版本切换成设定的版本--use-xcode-clang
:用于将xcode的clang版本切换回去
注:在执行下面命令的时候,须要退出xcode执行;且须要用sudo的形式运行。
仍然应用下面的project文件,在Build Settings增加参数,如图
-Xanalyzer -analyzer-checker=alpha.security.ArrayBoundV2
而后cmd+shift+b
在Xcode中也呈现了和报表同样的提醒。
对于checker的开发能够看这里。
weak的实现runtime
是如何实现在weak
润饰的变量的对象在被销毁时主动置为nil
的呢?一个广泛的解释是:runtime
对注册的类会进行布局,对于weak
润饰的对象会放入一个hash
表中。用weak
指向的对象内存地址作为key
,当此对象的援用计数为0
的时候会dealloc
,如果weak
指向的对象内存地址是a
,那么就会以a
为键在这个weak
表中搜寻,找到所有以a
为键的weak
对象,从而设置为nil
。
weak
指针的实现借助Objective-C
的运行时个性,runtime
通过 objc_storeWeak
, objc_destroyWeak
和 objc_moveWeak
等办法,间接批改__weak
对象,来实现弱援用。
objc_storeWeak
函数,将附有__weak
标识符的变量的地址注册到weak
表中,weak
表是一份与援用计数表类似的散列表。
而该变量会在开释的过程中清理weak
表中的援用,变量开释调用以下函数:
dealloc_objec_rootDeallocobject_disposeobjc_destructInstanceobjc_clear_deallocating
在最初的objc_clear_deallocating
函数中,从weak
表中找到弱援用指针的地址,而后置为nil
,并从weak
表删除记录。
对于ARC更多实现请参阅探索ARC
2.GDB与LLDB
咱们在开发iOS程序的时候经常会用到调试跟踪,如何正确的应用调试器来debug非常重要。xcode里有内置的Debugger,老版应用的是GDB,xcode自4.3之后默认应用的就是LLDB了。
GDB:
UNIX及UNIX-like下的调试工具。
LLDB:
LLDB是个开源的内置于XCode的具备REPL(read-eval-print-loop)特色的Debugger,其能够装置C++或者Python插件。
所以他们两个都是调试用的Debugger,只是LLDB是比拟高级的版本,或者在调试开发iOS利用时比拟好用,不然人家苹果为什么换成了LLDB了呢!
lldb与gdb命令名的对照表:http://lldb.llvm.org/lldb-gdb.html
LLDB的应用
在程序里你须要的中央设置断点。当断点断住的时候你就能看到咱们进入LLDB调试器了。
这时咱们就能够应用一些LLDB命令来进行一些调试了。
调试快捷键:(Xcode罕用快捷键)
command+shift+Y 关上调试窗口
command+Y 调试运行程序
command+option+P 持续
command+shift+O 跳过
command+shift+I 进入
command+shift+T 跳出
help命令
help会列出所有命令列表,用户加载的插件一般来说列在最初。
执行help 能够打印指定command的帮忙信息。
比方:help print会打印内建命令print的应用帮忙。
print命令
print命令的简化形式有prin pri p,唯独pr不能用来作为查看,因为会和process混同,侥幸的是p被lldb实现为特指print。
实际上你会发现,lldb对于命令的简称,是头部匹配形式,只有不混同,你能够随便简称某个命令。
例如:
最后面的(int)是类型。$是命令后果的援用名,应用$0能够进行print $0 + 7这样打印出17。
输入view 下 subview 的数量。
因为 subview 的数量是一个 int 类型的值,所以咱们应用命令p:(lldb)p (int)[[[self view] subviews] count]
间接调用办法扭转背景色彩之类
其实应用p,po,call都能够调用办法,只是p和po都是用于输入的有返回值的。call个别只在不须要显示输入,或是办法无返回值时应用。(lldb)p [self.view setBackgroundColor:[UIColor redColor]]
(lldb)p (void)[CATransaction flush]
上述的p个别应用call比拟好,因为办法是没有返回值的。
po命令
命令po跟p很像。p输入的是根本类型,po输入的Objective-C对象。调试器会输入这个 object 的 description。
例如:
expression命令
expression的简写就是e。能够用expression来申明新的变量,也能够扭转已有变量的值。咱们看到e申明的都是$结尾的变量。咱们在应用时也须要加上$符号。
例如:
创立新的变量
留神:如果下面这里输出以下命令,会产生谬误。阐明lldb无奈断定某一步的计算结果是什么数据类型,这时须要强制类型转换来通知lldb。
(lldb) p [[$array objectAtIndex:0] characterAtIndex:0]error: no known method '-characterAtIndex:'; cast the message send to the method's return typeerror: 1 errors parsing expression(lldb) p (char)[[$array objectAtIndex:0] characterAtIndex:0]'o'
批改已有变量
image命令
image 命令可用于寻址,有多个组合命令。比拟实用的用法是用于寻找栈地址对应的代码地位。 上面我写了一段代码
NSArray *arr=[[NSArray alloc] initWithObjects:@"1",@"2", nil];NSLog(@"%@",arr[2]);
这段代码有显著的谬误,程序运行这段代码后会抛出上面的异样:
*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayI objectAtIndex:]: index 2 beyond bounds [0 .. 1]'*** First throw call stack:( 0 CoreFoundation 0x0000000101951495 __exceptionPreprocess + 165 1 libobjc.A.dylib 0x00000001016b099e objc_exception_throw + 432 CoreFoundation 0x0000000101909e3f -[__NSArrayI objectAtIndex:] + 1753 ControlStyleDemo 0x0000000100004af8 -[RootViewController viewDidLoad] + 3124 UIKit 0x000000010035359e -[UIViewController loadViewIfRequired] + 5625 UIKit 0x0000000100353777 -[UIViewController view] + 296 UIKit 0x000000010029396b -[UIWindow addRootViewControllerViewIfPossible] + 587 UIKit 0x0000000100293c70 -[UIWindow _setHidden:forced:] + 2828 UIKit 0x000000010029cffa -[UIWindow makeKeyAndVisible] + 519 ControlStyleDemo 0x00000001000045e0 -[AppDelegate application:didFinishLaunchingWithOptions:] + 67210 UIKit 0x00000001002583d9 -[UIApplication _handleDelegateCallbacksWithOptions:isSuspended:restoreState:] + 26411 UIKit 0x0000000100258be1 -[UIApplication _callInitializationDelegatesForURL:payload:suspended:] + 160512 UIKit 0x000000010025ca0c -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] + 66013 UIKit 0x000000010026dd4c -[UIApplication handleEvent:withNewEvent:] + 318914 UIKit 0x000000010026e216 -[UIApplication sendEvent:] + 7915 UIKit 0x000000010025e086 _UIApplicationHandleEvent + 57816 GraphicsServices 0x0000000103aca71a _PurpleEventCallback + 76217 GraphicsServices 0x0000000103aca1e1 PurpleEventCallback + 3518 CoreFoundation 0x00000001018d3679 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 4119 CoreFoundation 0x00000001018d344e __CFRunLoopDoSource1 + 47820 CoreFoundation 0x00000001018fc903 __CFRunLoopRun + 193921 CoreFoundation 0x00000001018fbd83 CFRunLoopRunSpecific + 46722 UIKit 0x000000010025c2e1 -[UIApplication _run] + 60923 UIKit 0x000000010025de33 UIApplicationMain + 101024 ControlStyleDemo 0x0000000100006b73 main + 11525 libdyld.dylib 0x0000000101fe95fd start + 126 ??? 0x0000000000000001 0x0 + 1)libc++abi.dylib: terminating with uncaught exception of type NSException
当初,咱们狐疑出错的地址是0x0000000100004af8(能够依据执行文件名判断,或者最小的栈地址)。为了进一步精确定位,咱们能够输出以下的命令:
(lldb)image lookup --address 0x0000000100004af8(lldb)im loo -a 0x0000000100004af8
命令执行后返回:
Address: ControlStyleDemo[0x0000000100004af8] (ControlStyleDemo.__TEXT.__text + 13288)Summary: ControlStyleDemo`-[RootViewController viewDidLoad] + 312 at RootViewController.m:53
咱们能够看到,出错的地位是RootViewController.m的第53行。
设置断点触发条件
LLDB与GDB总结
原理
编译时输入带调试信息的程序,调试信息蕴含了指令地址、对应源代码及行号,指令实现后回调给调试器。
gdb/lldb常用命令
- b:设置断点break。
- r:运行run。
- n:单步调试next。
- s:跳入函数step。
- finish:跳出函数。
- p a:打印a的内容print。
- c:持续,直到下一个断点continue。
2.1打包编译组件
xctoo简介:facebook那帮人,耐不住每天打包的懊恼,搞了一些自动化组件工具。基于xcodebuild封装了一层造成了xctool。
xctool有哪些益处呢?
1、它能够从命令行构建和运行单元测试,这和Xcode.app从图形化界面上达到一样的成果。如果你为iOS设置了继续集成系统,那么这就十分重要了。你想要可能自动化运行测试,那些测试与你的开发人员在本地计算机上运行的完全相同,而xcodebuild不会用和Xcode.app雷同的形式来构建和运行测试。在Xcode 4中,苹果把单元测试集成到了Xcode中——与“构建”和“运行”一起,有一个新的“测试”动作;应用Xcode scheme,你能够抉择启用或者禁用哪些单元测试;如果你依赖于iOS模拟器(也就是应用程序测试)来编写测试,那么Xcode会主动载入模拟器并运行测试。这些都是很大的改良,但看起来苹果并没有把这些改良融入到xcodebuild中,那使得自动化构建和测试十分艰难。
2、 另一个重大的问题是构建和测试失败的报告。应用xcodebuild,你会失去大量文本输入,其中蕴含编译命令、编译谬误和正告以及OCUnit的测试输入。如果你想要主动确定哪个组件编译失败,或者哪个单元测试失败,那么你就须要编写本人的正则表达式解析器,那也是咱们和其余iOS社区中的人始终在做的工作。那会有成果,但切实很麻烦。有了xctool,咱们会让xcodebuild和OCUnit测试运行器把构建输入和测试后果作为JSON对象的结构化流输入。 这让咱们能够很容易地以须要的模式来显示构建和测试后果。例如,咱们创立了一个报表,以吸引人的、带有色彩的输入模式来显示后果(https://fpotter_public.s3.amazonaws.com/xctool-uicatalog.gif)。 还有人应用这来把测试后果输入为JUnit XML,那在风行的Jenkins构建零碎中会显示得很好。>>>>
xctool的应用:常用命令在他们工程的readme里有详细描述和例子:https://github.com/facebook/x...
xctool 不反对指定target如 -target
; 必须用scheme例如
- path/to/xctool.sh \
- -project YourProject.xcodeproj \
- -scheme YourScheme \
- build
xctool指定打印报告
- path/to/xctool.sh \
- -workspace YourWorkspace.xcworkspace \
- -scheme YourScheme \
- -reporter plain:/path/to/plain-output.txt \
- build
能够指定的格局如下
- pretty: a text-based reporter that uses ANSI colors and unicode symbols for pretty output (the default).
- plain: like _pretty_, but with no colors or unicode.
- phabricator: outputs a JSON array of build/test results which can be fed into the Phabricator code-review tool.
- junit: produces a JUnit/xUnit compatible XML file with test results.
- json-stream: a stream of build/test events as JSON dictionaries, one per line (example output).
- json-compilation-database: outputs a JSON Compilation Database of build events which can be used by Clang Tooling based tools, e.g. OCLint.
- user-notifications: sends notification to Notification Center when action is completed (example notifications).
- teamcity: sends service messages to TeamCity Continuous Integration Server
上面用xcodebuild和xctool理论入手打几个包来练练手。
一:测试了半天xcode8当前不反对xctool了 汗!!!
二:咱们回到xcodebuild上
project_path=$(pwd)
echo "project_path:${project_path}"
schemeName="FunnyProject"
outPutPath="${project_path}/outputDir"
echo "outputPath:${outPutPath}"
xcodebuild clean -workspace ${schemeName}.workspace -scheme ${schemeName} -configuration Debug
xcodebuild -project $schemeName.xcodeproj -scheme $schemeName clean
xcodebuild archive -project $schemeName.xcodeproj -scheme $schemeName -archivePath "${outPutPath}/${schemeName}.xcarchive" -configuration Debug
xcodebuild -archivePath "${outPutPath}/${schemeName}.xcarchive" -exportPath "${outPutPath}/${schemeName}.ipa" -exportOptionsPlist "${outPutPath}/ExportOptions.plist" -exportArchive
//这里有个参数exportOptionsPlist 须要收到打包导出文件夹里有这个文件,相当于一个配置文件,用这个文件来导出包,把这个文件copy到当前目录即可
-exportOptionsPlist "${outPutPath}/${schemeName}.plist"
xcodebuild -exportArchive -exportSigningIdentity 'Developer ID Application: My Team'
#xcodebuild -exportArchive -archivePath <xcarchivepath> -exportPath <destinationpath> -exportOptionsPlist <plistpath>
xctool -workspace GWMovie.xcworkspace -scheme GWMovie -sdk iphonesimulator run-tests
echo "${SECONDS}s"
3.包管理器
MacPorts
MacPorts依赖于BSD的软件包管理工具(port),它的工作形式是从仓库中下载软件包以及其依赖库,而后在本机中编译装置。
MacPorts的理念是尽量减少对系统现有库的依赖,因而它须要下载许多根底库,而后编译装置到零碎中。这样做最大的问题在于下载工夫长,编译工夫长,最大的益处就是不会毁坏零碎原有软件包。
Homebrew
Homebrew与MacPorts的工作形式相似,也是从仓库中下载软件包以及其依赖库,而后在本机中编译装置。
Homebrew的理念是尽量应用零碎中存在的库,且软件包都装置到/usr/local目录里,最大的益处就是下载编译工夫短于MacPorts,安装简单,且无需root用户权限来装置。
Homebrew简直快成为Mac OSX零碎下事实上的规范软件包管理工具了
CocoaPods
iOS 和 OS X下的一个第三方库管理工具,相似的iOS工具还有Carthage(比拟轻量级,须要手动配置,非侵入式),与Java里的Maven也比拟相似,然而没有maven的构建、运行程序、打包等性能,仅仅是库依赖配置和库版本管理工具。
作用:依赖库版本治理、库依赖主动配置;
零碎架构
一、iOS零碎架构
用户体验层(The User Experience Layer)
应用软件开发框架层(The Application Frameworks Layer)
外围开发框架层(The Core Frameworks)
零碎内核核心层(Darwin)
概述:
1、Darwin
Darwin是一种相似unix的操作系统,他的外围是XNU。
XNU是一种混合式内核。联合了mach与BSD两种内核。
Mach是微内核实现。
BSD实现在Mach的下层,这一层提供的API 反对了POSIX规范模型。在XNU中次要实现了一些高级的API与模块。
1.1、Mach 微内核简介
在XNU中次要实现以下几个性能:
过程与线程的形象
虚拟内存治理
任务调度
过程间通信
1.2、BSD 内核简介
BSD 实现在Mach的下层,这一层提供的API 反对了POSIX规范模型。在XNU中次要实现了一些高级的API与模块。
UNIX 过程模型。
POSIX 线程模型即pthread,以及相干的同步性能。
UNIX的用户与组治理。
网络协议栈(BSD Socket API),合乎POSIX 模型。
文件系统/设施零碎。
1.3、libKern
实现了一个C+ +的子集(以库的模式为反对C+ +提供了运行时),为I/O kit 提供基础设施
1.4、I/O kit
I/O kit 是XNU 不同于其余操作系统的设施驱动框架。IOKit是一个面向对象的驱动模型框架,它是晚期DriverKit的一个翻版,Driver Kit是应用Objective-C写的,而IOKit是一个C+ +的驱动架构,它在DriverKit的根底上做了很大的改良,比方IOKit能够写在用户空间跑的驱动(尽管大多仍是跑在内核空间上的),因此驱动挂了而零碎不会挂。另外IOKit思考到了计算机倒退的趋势,所以在电源治理、即插即用、动静加载上做得更好。
两个根底框架
iOS应用程序基于Foundation和UIKit框架
1. Foundation
在你开发程序时,次要应用框架就是Foundation和UIKit,因为它们蕴含了你须要的大部分货色。
- Foundation框架为所有的应用程序提供根本零碎服务
你的应用程序,UIKit和其它的框架都是建设在Foundation框架下面的。Foundation框架是用Object-C对CoreFoundation框架里许多个性的封装。 - 应用Foundation能够:
- 创立和治理汇合,比方数组和字典
- 拜访存储在应用程序里的图片和其它资源
- 创立和治理字符串
- 提交和接管告诉
- 创立日期和工夫对象
- 主动发现IP网络上的设施
- 操作URL流
- 执行异步代码
你曾经在《Your First iOSApp》里应用到了Foundation框架。比方,你应用一个NSString类的实例存储用户输出的userName。你还应用了Foundation框架的initWithFormat办法创立了一个字符串。
UIKit框架提供创立基于触摸用户界面的类
2. UIKit
所有的iOS应用程序都基于UIKit,你不能是应用程序脱离这个框架。UIKit提供了在屏幕上绘制的机制,捕捉事件,和创立通用用户界面元素。UIKit也通过治理显示在屏幕上的组件来组织简单的我的项目。
- 应用UIKit能够:
- 构建和治理你的用户界面
- 捕捉触摸和基于挪动的事件
- 出现文字和web内容
- 优化你的多任务程序
- 创立定制的用户界面元素
在《YouFirstiOS AppTutorial》里,你也应用到了UIKit。当你认真查看程序是怎么运行起来的时候,你会看到UIApplicationMain函数创立一个UIApplication类的实例,这个实例会捕捉进来的用户事件。你实现UITextFieldDelegate协定,而后在用户按下Done时暗藏键盘。实际上,你是在应用UIKit创立用户界面上的UITextField,UILabel,和UIButton类。
你须要晓得的其它重要的框架
Core Data , Core Graphics, CoreAnimation,和OpenGLES框架都是高级的技术。所以这些框架对于你开发应用程序也是很重要的,它们都须要工夫去学习和把握。
1. CoreData框架管着理应用程序数据模型
Core Data提供对象的治理,应用CoreData,你能够创立模型对象,并治理这些对象。你治理这这些对象间的分割并批改数据。CoreData提供的内建SQLlite技术能够高效的治理数据。
应用Core Data能够:
- 在库里存储和接管对象
- 提供根本的undo/redo
- 主动验证属性值
- 过滤、分组和优化内存中的数据
- 用[NSFetchedResultsController]治理表视图中的后果
- 反对基于文档的应用程序
2. CoreGraphics框架帮忙你创立图形
高质量的图形对于所有的iOS应用程序都是很重要的。在iOS中最简略且最快捷的创立图形的形式是应用UIKit框架提供的基于预渲染图形的视图和控件,而后让UIKit和iOS实现绘制。然而当你须要创立简单的图形时,CoreGraphics则提供了更底层的库来帮忙你。
应用Core Graphics能够:
- 创立基于门路的绘图
- 抗锯齿渲染
- 增加梯度、图片和色彩
- Use coordinate-spacetransformations.
- 创立、显示和剖析PDF文档
3. CoreAnimation容许你创立高级的动画和虚构成果
UIKit提供建设在Core Animation之上的动画。如果你须要比UIKit能力更高级的性能,能够间接应用CoreAnimation。Core Animation接口蕴含在Quartz Core框架里。应用CoreAnimation能够创立嵌套的对象,并且能够对它们操作、旋转、缩放和转换。应用Coreanimation,你能够创立动静的用户界面而不必应用更底层的图形API,如OpenGL ES。
应用Core Animation能够:
- 创立定制动画
- 增加定时函数和图形
- 反对帧动画
- Specify graphical layoutconstraints.
- Group multiple-layerchanges into anatomic update.
4. OpenGL ES框架提供2D和3D绘图工具
OpenGL ES反对2D和3D绘图,Apple的OpenGL ES实现通过硬件提供了高速的全屏游戏式的应用程序。
应用OpenGL ES能够:
- 创立2D和3D图形
- 创立更简单的图形,比方数据虚拟化、模仿航行,或者视频游戏
- 拜访底层图形设施
依据须要向我的项目中增加其它框架
还有许多框架能够增加到你的程序里。当你决定应用一个框架但我的项目里却没有引入这个框架时,你就须要将它退出到你的我的项目里。
将别的框架增加到工程里
1 关上工程
2 点击我的项目名,显示project editor
3 在TARGETS列表中选中要增加框架的工程
4 点击project editor顶部的BuildPhases
5 点击Link Binary WithLibraries后面的三角形关上这个分组
6 通过点击增加(+)来增加一个框架
7 在列表中抉择一个框架,而后点击Add按钮