面试心声
最近在准备面试时候,回顾了一些过去写的项目和知识点,从底层和原理的角度重新去看代码和问题,发现了不少有意思的地方!
如果您觉得里面的问题不错,值得在面试准备的时候学习看看,之前看了很多面试题,感觉要不是不够就是过于冗余,于是我将网上的一些面试题进行了删减和重排,现在分享给大家!!!
收集梳理了一些iOS相关的问题,其中大部分都是大小厂面试或者面试其他人用到的,能命中大部分的面试和日常工作,更希望你可以用它来检验自己
电子版答案:
由于答案太多,我做了一个PDF文档,由于简书不能上传文件,需要答案可以加小编我的 iOS交流群761407670,密码‘000‘’在里面获取文档,也欢迎招聘者,找工作的来,提供一个更大的平台
1.给定一个字符串,输出本字符串中只出现一次并且最靠前的那个字符的位置?比如“abaccddeeef”则是b,输出2
答: int main()
{
char a[80] = "abaccddeeef0";
char ch;
int i, m, b[80];
int flag = 0;
ch = getchar();//获取一个字符
m = strlen(a);
for (i = 0; i < m; ++i){
if (a[i] == ch){//找到了,直接判断是否相等
b[flag] = i+1;//记录位置
flag += 1;
}
}
if (flag == 0)printf ("no");
else {
printf ("%dn", flag);
for (i = 0; i < flag; i++){//对位置进行输出,用循环
printf ("%d ", b[i]);
}
printf ("n");
}
return 0;
}
2.实现一个冒泡排序或者快速排序
答:冒泡排序:
intarray[5] = { 28,27,36,45,8};
for (int i = 0; i < 4; i++) {
for(int j = 0; j < 4; j++) {
if (array[j] > array [j + 1]){
int temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
}}}
for(int i = 0; i < 5; i++) {
printf("%dn",array[i]);}
3.请编写一个函数用于计算阶乘
答: int f(int i)
{intt=1,j;
for(j=1;j<=i;j++)
t=t*j;
return t;
}
4.Cocoa Touch提供了几种Core
Animation过渡类?
答:Cocoa Touch提供了4种Core
Animation过渡类型,分别为:交叉淡化、推挤、显示和覆盖。
5.iOS平台怎么做数据的持久化?coredata和sqlite有无必然联系?coredata是一个关系型数据吗?
答:数据的持久化本质上都是就是写文件,但从逻辑上又分成很多种,比如写入沙盒,比如存到网络上,比如写入数据库。
core data是对sqlite的封装,因为sqlite是c语言的api,然而有人也需要obj-c的api,所以有了core data ,另外,core data不仅仅是把c的api翻译成oc的api,还提供了一些管理的功能,使用更加方便。
App升级之后数据库字段或者表有更改会导致crash,CoreData的版本管理和数据迁移变得非常有用,手动写sql语句操作还是麻烦一些。
CoreData不光能操纵SQLite,CoreData和iCloud的结合也很好,如果有这方面需求的话优先考虑CoreData。
CoreData并不是直接操纵数据库,比如:使用CoreData时不能设置数据库的主键,目前仍需要手动操作。
6.Object-c的类可以多重继承么?可以实现多个接口么?category是什么?重写一个类的方式用继承好还是分类好?为什么?
答: Object-c的类不可以多重继承;可以实现多个接口,通过实现多个接口可以完成C++的多重继承;Category是类别,一般情况用分类好,用Category去重写类的方法,仅对本Category有效,不会影响到其他类与原有类的关系。
7.#import跟#include有什么区别,@class呢?#import<>跟#import””有什么区别?
答: #import是Objective-C导入头文件的关键字,#include是C/C++导入头文件的关键字,使用#import头文件会自动只导入一次,不会重复导入,相当于#include和#pragma once;@class告诉编译器某个类的声明,当执行时,才去查看类的实现文件,可以解决头文件的相互包含;#import<>用来包含系统的头文件,#import””用来包含用户头文件。
8.属性readwrite,readonly,assin,retain,copy,nonatomic各是什么作用,在哪种情况下用?
答: readwrite是可读可写特性;需要生成getter方法和setter方法时
readonly是只读特性只会生成getter方法不会生成setter方法;不希望属性在类外改变
assign是赋值特性,setter方法将传入参数赋值给实例变量;仅设置变量时;
retain表示持有特性,setter方法将传入参数先保留,再赋值,传入参数的retaincount会+1;
copy表示拷贝特性,setter方法将传入对象复制一份;需要完全一份新的变量时。
nonatomic非原子操作,决定编译器生成的setter
getter是否是原子操作,atomic表示多线程安全,一般使用nonatomic
9.写一个setter方法用于完成@property(nonatomic,
retain)NSString name;写一个setter方法用于完成@property(nonatomic, copy)NSString name;
答: -(void)setName:(NSString *) str
{
[str retain];
[name release];
name = str;
}
- (void)setName:(NSString *)str
{
id t = [str copy];
[name release];
name = t; }
10.对于语句NSString *obj =
[[NSData alloc] init]; obj在编译时和运行时分别是什么类型的对象?
答:编译时是NSString的类型;运行时是NSData类型的对象
11.当前已经编程实现函数:int
rand100().该函数可返回0~99的随机整数,且可以保证等概率.请利用该函数实现int rand10000(),要求等概率返回0~9999的随机数.(不可使用其他的系统函数)
12.汤姆现在要在家里举行宴会,他虽然有很多筷子,但这些筷子的长度并不完全相同,先已知每根筷子的长度,要求每位客人都能拿到两根长度相同的筷子
,求最多可邀请的客人数.
编程实现:int getMax(int arrLength[N])
13.现有一个整数序列,你可以交换其中的任意两个数以得到一个新序列.求共能得到多少种可能结果.(注意:3,3,3,3无论怎么交换,只能得到一个序列)
编程实现:int getTotal(int arrOrigin[N])
14.现有一个M行N列的数组,要求安装反向斜对角线(右上->左下)的方式,打印该数组.编程实现:intprintMatrixint arrMatrix[M]
下面样例的打印顺序为:
0->1->4->2->5->8->3->6->9->7->10->11
123
4567
8910 11
15.在UIKit中,frame与bounds的关系是( C )
A. frame是bounds的别名
B. frame是bounds的继承类
C. frame的参考系是父规图坐标, bounds的参考系是自身的坐标
D.frame的参考系是自身坐标,bounds的参考系是父规图的坐标
16.一个类的delegate(代理)的作用不正确的是( D )
A.delegate中的函数在其他类中实现
B.主要用于不同类型的对象之间一对一传递消息
C.没有指派则不会触发
D.可以一个对象的delegate指派给多个其他类型的对象
17.下面关于Objective-C内存管理的描述错误的是(A )
A.当使用ARC来管理内存时,对象的retain,dealloc方法不会被调用
B.autoreleasepool在drain的时候会释放在其中分配的对象
C.当使用ARC来管理内存时,在线程中大量分配对象而不用autoreleasepool则可能会造成内存泄露
D.在使用ARC的项目中不能使用NSZone
18.下面block定义正确的是( A )
A.tyoedef void(^SuccessBlock)(BOOLsuccess);
B. tyoedef void(^SuccessBlock)(NSStringvalue,BOOL success);
C. tyoedef void^(SuccessBlock)(NSStringvalue,BOOL success);
D. tyoedef void^(SuccessBlock)(NSString*value);
19.UIButton从子类到父类一次继承自:( D )
A. UIView-> UIViewController->UIController
B. UIResponder-> UIControl-> UIView
C. UIControl-> UIResponder->UIViewController
D. UIControl-> UIView-> UIResponder
20.下列关于iOS开发中类方法的使用描述,错误的是:( C )
A.类方法可以调用类方法
B.类方法不可以调用实例方法,但是类方法可以通过创建对象来访问实例方法
C.类方法不可以使用实例变量,包括self(可以使用self)
D.类方法作为消息,可以被发送到类或者对象里面去
31.什么情况下使用关键字weak和assign有何不同?
答:assign指针赋值,不对引用计数操作,使用之后如果没有置为nil,可能就会产生野指针;而weak一旦不进行使用后,永远不会使用了,就不会产生野指针!
32.Object-C的类可以多重继承么?可以实现多个接口么?Category是什么?重写一个类方法的方法用继承好还是分类好?为什么?
答: Object-c的类不可以多重继承;可以实现多个接口,通过实现多个接口可以完成C++的多重继承;Category是类别,一般情况用分类好,用Category去重写类的方法,仅对本Category有效,不会影响到其他类与原有类的关系。
32.如何用iOS设备进行性能测试?
答: Profile-> Instruments ->Time Profiler
33.我们说的oc是动态运行时语音是什么意思?
答案:多态。主要是将数据类型的确定由编译时,推迟到了运行时。这个问题其实浅涉及到两个概念,运行时和多态。简单来说,运行时机制使我们直到运行时才去决定一个对象的类别,以及调用该类别对象指定方法。多态:不同对象以自己的方式响应相同的消息的能力叫做多态。意思就是假设生物类(life)都用有一个相同的方法-eat;那人类属于生物,猪也属于生物,都继承了life后,实现各自的eat,但是调用是我们只需调用各自的eat方法。也就是不同的对象以自己的方式响应了相同的消息(响应了eat这个选择器)。因此也可以说,运行时机制是多态的基础。
34.你的项目什么时候选择使用GCD,什么时候选择NSOperation?
答:项目中使用NSOperation的优点是NSOperation是对线程的高度抽象,在项目中使用它,会使项目的程序结构更好,子类化NSOperation的设计思路,是具有面向对象的优点(复用、封装),使得实现是多线程支持,而接口简单,建议在复杂项目中使用。项目中使用GCD的优点是GCD本身非常简单、易用,对于不复杂的多线程操作,会节省代码量,而Block参数的使用,会是代码更为易读,建议在简单项目中使用。
35.读文件是输入流还是输出流?
东西读入内存就是输入流东西从内存写到记录存储输出流而我们本身就以记录存储为原点所有会有不解的感觉~java io流按照java io流的方向可以分为输入流和输出流输入流是将资源数据读入到缓冲Buffer中,输出流是将缓冲Buffer中的数据按照指定格式写出到一个指定的位置,所以这两个流一般同时使用,才有意义。例如你要做文件的上传,你要先用输入流将待上传文件读入缓冲,然后用输出流将文件写出到网络服务器的一个位置,则上传成功;若是文件下载,则先获得输入流,来读取网络服务器中的一个文件,然后用输出流写到本地的一个文件中;还有例如文件的拷贝,也是先用输入流读再用输出流写出去的很好的例子,你可以先做一个小例子试试,对你理解java io有帮助
36.简述CALayer和UIView的关系
答:UIView和CALayer是相互依赖的关系。UIView依赖与calayer提供的内容,CALayer依赖uivew提供的容器来显示绘制的内容。归根到底CALayer是这一切的基础,如果没有CALayer,UIView自身也不会存在,UIView是一个特殊的CALayer实现,添加了响应事件的能力。
结论:
UIView来自CALayer,高于CALayer,是CALayer高层实现与封装。UIView的所有特性来源于CALayer支持。
37.声明一个静态方法和一个实例方法
答:先说实例方法,当你给一个类写一个方法,如果该方法需要访问某个实例的成员变量时,那么就将该方法定义成实例方法。一类的实例通常有一些成员变量,其中含有该实例的状态信息。而该方法需要改变这些状态。那么该方法需要声明成实例方法。
静态方法正好相反,它不需要访问某个实例的成员变量,它不需要去改变某个实例的状态。我们把该方法定义成静态方法。
38.常见的Object-C的数据类型有哪些?和Cd基本数据类型有什么区别?
答: object-c的数据类型有nsstring,nsnumber,nsarray,nsmutablearray,nsdata等等,这些都是class,创建后便是对象,而c语言的基本数据类型int,只是一定字节的内存空间,用于存放数值;而object-c的nsnumber包含有父nsobject的方法和nsnumber自己的方法,可以完成复杂的操作。
39.UIView的动画效果有哪些
如UIViewAnimationOptionCurveEaseInOut
UIViewAnimationOptionCurveEaseIn
UIViewAnimationOptionCurveEaseOut
UIViewAnimationOptionTransitionFlipFromLeft
UIViewAnimationOptionTransitionFlipFromRight
UIViewAnimationOptionTransitionCurlUp
UIViewAnimationOptionTransitionCurlDown
40.你了解svn,cvs等版本控制工具么?
答:了解.
41.静态链接库(了解一下)
答:静态库是程序代码的集合,是共享代码的一种方式
静态库是闭源的存在形式.a和.framework
连接时,静态库会被完全的复制到可执行文件中,被多次使用就会有冗余拷贝,相当于java里的jar包,把一些类编译到一个包中,在不同的工程中如果导入此文件就可以使用里面的类,
42.什么是沙箱模型?哪些操作是属于私有api范畴?
答:1、应用程序可以在自己的沙盒里运作,但是不能访问任何其他应用程序的沙盒。
2、应用程序间不能共享数据,沙盒里的文件不能被复制到其他应用程序文件夹中,也不能把其他应用程序文件夹中的文件复制到沙盒里。
3、苹果禁止任何读、写沙盒以外的文件,禁止应用程序将内容写到沙盒以外的文件夹中。
4、沙盒根目录里有三个文件夹:Documents,一般应该把应用程序的数据文件存到这个文件夹里,用于存储用户数据或其他应该定期备份的信息。Library,下有两个文件夹,Caches存储应用程序再次启动所需的信息,Preferences包含应用程序偏好设置文件,不过不要在这里修改偏好设置。temp,存放临时文件,即应用程序再次启动不需要的文件。
沙盒根目录里有三个文件夹分别是:documents,tmp,Library。
1、Documents目录:您应该将所有de应用程序数据文件写入到这个目录下。这个目录用于存储用户数据或其它应该定期备份的信息。
2、AppName.app目录:这是应用程序的程序包目录,包含应用程序的本身。由于应用程序必须经过签名,所以您在运行时不能对这个目录中的内容进行修改,否则可能会使应用程序无法启动。
3、Library目录:这个目录下有两个子目录:Caches和Preferences
Preferences目录:包含应用程序的偏好设置文件。您不应该直接创建偏好设置文件,而是应该使用NSUserDefaults类来取得和设置应用程序的偏好.
Caches目录:用于存放应用程序专用的支持文件,保存应用程序再次启动过程中需要的信息。
4、tmp目录:这个目录用于存放临时文件,保存应用程序再次启动过程中不需要的信息。
iOS沙盒(sandbox)中的几个目录获取方式:
//获取沙盒主目录路径
NSString *homeDir = NSHomeDirectory();
//获取Documents目录路径
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docDir = [paths objectAtIndex:0];
//获取Caches目录路径
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *cachesDir = [paths objectAtIndex:0];
//获取tmp目录路径
NSString *tmpDir = NSTemporaryDirectory();
//获取当前程序包中一个图片资源(apple.png)路径
NSString *imagePath = [[NSBundle mainBundle] pathForResource:@"apple" ofType:@"png"];
UIImage *appleImage = [[UIImage alloc] initWithContentsOfFile:imagePath];
例子:
NSFileManager* fm=[NSFileManagerdefaultManager];
if(![fm fileExistsAtPath:[selfdataFilePath]]){
//下面是对该文件进行制定路径的保存
[fm createDirectoryAtPath:[selfdataFilePath] withIntermediateDirectories:YES attributes:nil error:nil];
//取得一个目录下得所有文件名
NSArray *files = [fm subpathsAtPath: [selfdataFilePath] ];
//读取某个文件
NSData *data = [fm contentsAtPath:[selfdataFilePath]];
//或者
NSData *data = [NSDatadataWithContentOfPath:[self dataFilePath]];
}
43.协议是什么?有什么作用?
协议:声明一系列的方法,可由任何类实施,即使遵守该协议的类没有共同的超类。协议方法定义了独立于任何特定类的行为。简单的说,协议就是定义了一个接口,其他类负责来实现这些接口。如果你的类实现了一个协议的方法时,则说该类遵循此协议。
协议的作用:
1.定义一套公用的接口(Public)
@required:必须实现的方法
@optional:可选实现的方法(可以全部都不实现)
2.委托代理(Delegate)传值:
它本身是一个设计模式,它的意思是委托别人去做某事。
比如:两个类之间的传值,类A调用类B的方法,类B在执行过程中遇到问题通知类A,这时候我们需要用到代理(Delegate)。
又比如:控制器(Controller)与控制器(Controller)之间的传值,从C1跳转到C2,再从C2返回到C1时需要通知C1更新UI或者是做其它的事情,这时候我们就用到了代理(Delegate)传值。
44.你在开发大型项目时,如何进行内存泄露检测的?
可以通过xcode的自带工具run---start with performance tool里有instruments下有个leaks工具,
启动此工具后,运行项目,工具里可以显示内存泄露的情况,双击可找到源码位置,可以帮助进行内存泄露的处理。
45.你实现过一个框架或者库以供别人使用么?如果有,请谈一谈构建框架或者库是的经验;如果没有,请设想和设计框架的public的API,并指出大概需要如何做,需要注意一些什么方面,来方便别人容易地使用你的框架.
46.app从创建应用到上架过程(appstore)
在你开始将程序提交到App Store之前,你需要有一个App ID,一个有效的发布证书,以及一个有效的Provisioning profile。
在itunesconnect网站上,创建app应用,设置对应信息,上传app打包文件,提交等待审核
47.用你熟悉的语音,编程实现Fibonacci数列:int F(intn);
Fibonacci数列递推式F(n) = F(n-1) +F(n-2)
F(1) = 1
F(2) = 2
F(3) = 3
F(4) = 5
F(5) = 8
int F(int n){
if(n == 1){
return1;
}
return f(n-1)+f(n-2);
}
48.给定两个排好序的数组A,B,请写一个函数,从中找出他们的公共元素:findCommon(A,
B)并列举其他可能的查找方法,越多越好
例如:
Array A = [1, 3, 5, 6, 9]
Array B = [2, 3, 6, 8, 10]
返回结果= [3, 6]
void FindCommon(int a, int b, int n)
{
int i = 0;
int j = 0 ;
while(i < n && j < n){
if (a[i] < b[j])
++i ;
else if(a[i] == b[j])
{
cout << a[i] << endl ;
++i ;
++j ;
}
else// a[i] > b[j]
++j ;
}
51.KVO的实现原理?
答:KVO:当指定的对象的属性被修改了,允许对象接收到通知的机制。
52.如何给一个对象的私有属性赋值?
答:利用KVC即键值编码来给对象的私有属性赋值.
53.block的本质是什么?为啥在block里面更改外面变量的值,要给外面的变量加_block修饰,加_block修饰的原理是什么?
答: (1) block本质是一个数据类型,多用于参数传递,代替代理方法, (有多个参数需要传递或者多个代理方法需要实现还是推荐使用代理方法),少用于当做返回值传递. block是一个OC对象,它的功能是保存代码片段,预先准备好代码,并在需要的时候执行.
(2)因为使用block代码块可能会引起内部循坏引用,所以应在block定义前加上修饰
54.block在哪种情况下会造成循环引用,如何解决?
答:(1)从两方面分析造成循环引用问题
当self拥有一个block的时候,在block又调用self的方法(或者self所拥有的某个属性)。形成你中有我,我中有你,这种时候会造成循环引用
把某个实例变量变成本地临时变量,强引用将直接指向这个本地临时变量,但本地临时变量一般都会很快释放,所以一般考虑第一种情况
(2)解决方案:对block进行修饰__weak(arc)或__block(mrc)
55.NSURLSession在什么情况下回存在循环引用的问题,怎么解决?
答: (1)在使用NSURLSession签订其代理的时候会存在循环引用问题,因为其代理是retain强引用
(2)解决方案
(1)在下载完成后取消NSURLSession会话并释放Session,赋值为nil。
(2)再视图将要消失时也执行同样的操作。为了防止没有下载完成就跳转控制器。
具体如下:
/*_视图将要消失的时候,取消session_/
- (void)viewWillDisappear:(BOOL)animated
{
[superviewWillDisappear:animated];
//任务完成,取消NSURLSession
[self.sessioninvalidateAndCancel];
//释放会话
self.session =nil;
}
56.如何自己实现GET缓存?
答:1.使用GET请求数据
2.iOS系统SDK已经做好了缓存。需要的仅仅是设置下内存缓存大小、磁盘缓存大小、以及缓存路径,代码如下
NSURLCache urlCache = [[NSURLCache alloc] initWithMemoryCapacity:4 1024 1024 diskCapacity:20 1024 * 1024 diskPath:nil];
[NSURLCache setSharedURLCache:urlCache];
57.在使用SQLite过程中,如果多条线程同时操作同一数据库会造成什么问题,怎么解决?
答:(1)容易造成系统崩溃
(2)解决方案:开启第3种串行模式,使用一个类(单例方式)操作数据库。
58.如果提交一个Json格式的数据给后台服务器,后台服务器返回的是一段普通文字,用NSURLConnection/NSURLSession/AFN分别如何实现?
答:1.使用NSURLConnection发送请求的步骤很简单
(1)创建一个NSURL对象,设置请求路径(设置请求路径)
(2)传入NSURL创建一个NSURLRequest对象,设置请求头和请求体(创建请求对象)
(3)使用NSURLConnection发送NSURLRequest(发送请求)
2.使用NSURLSession发送请求的步骤很简单
1)确定请求路径(一般由公司的后台开发人员以接口文档的方式提供),GET请求参数直接跟在URL后面
2)创建请求对象(默认包含了请求头和请求方法【GET】),此步骤可以省略
3)创建会话对象(NSURLSession)
4)根据会话对象创建请求任务(NSURLSessionDataTask)
5)执行Task
6)当得到服务器返回的响应后,解析数据(XML|JSON|HTTP)
59.请描述一下SDWebImage内部实现的原理
答:SDWebImage底层实现有沙盒缓存机制,主要由三块组成
1、内存图片缓存
2、内存操作缓存
3、磁盘沙盒缓存
60.你对runtime都有哪些了解,你在实现开发过程中,或是你在所使用的第三方框架中,有没有使用过runtime的,如果有,请你描述一下其内部实现机制
答:Runtime:runtime是一套比较底层的纯C语言API,属于1个C语言库,包含了很多底层的C语言API。在我们平时编写的OC代码中,程序运行过程时,其实最终都是转成了runtime的C语言代码, runtime算是OC的幕后工作者.
(http://www.w2bc.com/article/126999网址中搜索:其实最终都是转成了runtime的C语言代码)
61.线程间怎么通信?
(1)GCD:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{
//下载图片
UIImage *image = nil;
dispatch_async(dispatch_get_main_queue(),^{
//回到主线程
});
(2)NSThread的线程通信
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{
//下载图片
UIImage *image = nil;
[selfperformSelector:@selector(settingImage:) onThread:[NSThread mainThread]withObject:image waitUntilDone:YES modes:nil];
}
这种情况也适用于子线程之间的通信。
62.网络图片处理问题中怎么解决一个相同的网络地址重复请求的问题?
答案:利用字典图片地址为key,下载操作为value
63.自动释放池底层怎么实现?
答:自动释放池以栈的形式实现:当你创建一个新的自动释放池时,它将被添加到栈顶.当一个对象收到发送autorelease消息时,他被添加到当前线程的处于栈顶的自动释放池中,当自动释放池被回收时,他们从栈中被删除,并且会给池子里面所有的对象都会做一次release操作
64.不用中间变量,用两种方法交换A和B的值
A = A+B;
B = A - B;
A = A - B;
65.简单描述一下客户端的缓存机制?
答案:无法简述,详细了解下,明白了够装逼就好http://www.cnblogs.com/wendingding/p/3950198.html
66.控制器View的生命周期及相关函数是什么?你在开发中是如何用的?
1.在视图显示之前调用viewWillAppear;该函数可以调用多次;2.视图显示完毕,调用viewDidAppear;
3.在视图消失之前调用viewWillDisAppear;该函数可以调用多次(如需要);
4.在布局变化前后,调用viewWill/DidLayoutSubviews处理相关信息;
67.NSRunLoop的实现机制,及在多线程中如何使用?
答案:NSRunLoop是iOS的消息机制的处理模式
1NSRunloop的主要作用:控制runloop里面线程的执行和休眠,在有事情做的时候使挡墙NSRunloop控制的线程工作,没有事情做让当前runloop的控制线程休眠.2.runloop就是一直在循环检测,从线程start到线程end,检测inputsourse(如点击,双击等操作)异步时间,检测timesourse同步事件,见到检测到输入源会执行处理函数,首先会产生通知,corefunction向线程添加runloop observers来监听事件,意在监听事件发生时来做处理。
3.runloopmode是一个集合,包括监听:事件源,定时器,以及需通知的runloop observers
1.只有在为你的程序创建次线程的时候,才需要运行run loop。对于程序的主线程而言,run loop是关键部分。Cocoa提供了运行主线程run loop的代码同时也会自动运行run loop。IOS程序UIApplication中的run方法在程序正常启动的时候就会启动run loop。如果你使用xcode提供的模板创建的程序,那你永远不需要自己去启动run loop
2.在多线程中,你需要判断是否需要run loop。如果需要run loop,那么你要负责配置run loop并启动。你不需要在任何情况下都去启动run loop。比如,你使用线程去处理一个预先定义好的耗时极长的任务时,你就可以毋需启动run loop。Run loop只在你要和线程有交互时才需要
68.简单说一下APP的启动过程,从main文件开始说起
进入main函数,在main.m的main函数中执行了UIApplicationMain这个方法,这是ios程序的入口点!
int UIApplicationMain(int argc, char argv[], NSString principalClassName, NSString *delegateClassName)
argc、argv:ISO C标准main函数的参数,直接传递给UIApplicationMain进行相关处理即可
principalClassName:指定应用程序类,该类必须是UIApplication(或子类)。如果为nil,则用UIApplication类作为默认值
delegateClassName:指定应用程序类的代理类,该类必须遵守UIApplicationDelegate协议
此函数会根据principalClassName创建UIApplication对象,根据delegateClassName创建一个delegate对象,并将该delegate对象赋值给UIApplication对象中的delegate属性
lUIApplication对象会依次给delegate对象发送不同的消息,接着会建立应用程序的main runloop(事件循环),进行事件的处理(首先会调用delegate对象的application:didFinishLaunchingWithOptions:)
程序正常退出时这个函数才返回。如果进程要被系统强制杀死,一般这个函数还没来得及返回进程就终止了
69.第三方API你是怎么用的?
cocoa pod导入
70.用预处理指令#define声明一个常数,用以表明一年中有多少秒?(忽略闰年问题)
答:#define second 365_24_60*60
91.UITableView需要实现哪些代理?列出UITableView代理中必须实现的与其他一些常用的函数.
答:
-( NSInteger )tableView:( UITableView *)tableViewnumberOfRowsInSection:( NSInteger)section;
一组有多少行
-( UITableViewCell )tableView:( UITableView )tableViewcellForRowAtIndexPath:(NSIndexPath *)indexPath;
每行中的cell的实现以上两个方法为必须要实现的
常用的有
- ( void )tableView:( UITableView _)tableViewdidSelectRowAtIndexPath:( NSIndexPath_)indexPath
选中以后事件设置
-( CGFloat )tableView:( UITableView _)tableViewheightForRowAtIndexPath:( NSIndexPath_)indexPath
设置cell的高度
等等。。。。。
92.在iOS上开发一个应用程序时怎么做的?
答:首先,要有一个MAC系统(买一台苹果电脑,苹果本或者MACmini),没有这个条件可以装一个黑苹果的mac系统或者装一个虚拟机。然后装一个X-CODE开发环境。要是学习ios开发的话,这些就可以了。如果要开发、上线的话,就得准备iphone/ipod、ipad做为测试机,到苹果申请一个开发者账号,每年的年费99美元。再然后接着就可以开发你的程序了,开发完毕之后,发布到App store上面,通过审核就可以了。
*93.C++和Objective-C的混合使用,以下描述错误的是()
//未找到答案或是C++JAVA
A. cpp文件只能使用C/C++代码
B. cpp文件include的头文件中,可以出现objective-C的代码
C. mm文件中混用cpp直接使用即可
D. cpp使用objective-C的关键是使用接口,而不能直接使用代码
*94.以下哪一段代码不会抛出异常( C& D )
A. NSArray _array = @[1, 2, 3];NSNumber_number = array[3];// @[@1,@ 2,@ 3]
B. NSDictionary *dict = @{@”key”:
nil};//value不能为空
C. NSString str = nil; NSString str2 =[str substringFromIndex:3];
D. NSString str = @”hi”;NSString str2 =[str substringFromIndex:3];
*95.在没有navigationController的情况下,要从一个ViewController切换到另一个ViewController应该()
A.{self.navigationControllerpushViewController:nextViewController animated:YES};
B.{self .viewaddSubview:nextViewController}
C. {selfpresentModalViewController:nextViewController animated:YES};
D. {selfpushViewController:nextViewController animated:YES};
分析:A、C都需要有navigationController,B一个控制器的view是无法加载另一个控制器的view的,所以选C!
*96.关于下面线程管理错误的是()
//不确定
A.GCD在后端管理着一个线程池
B.NSOperationQueue是对NSthread的更高层的封装,对
C.NSThread需要自己管理线程的生命周期
D.GCD可以根据不同优先级分配线程,对
*97.iOS中的数据持久化方式(D)
A.属性列表
B.对象归档
C.SQLite和CoreData
D.以上全部+对象归档
98.设有一下宏定义:
defineN4
defineY(n)((N + 1) * n)
则执行语句: Y(5 + 1)为:(26)
99.如下程序用于把"blue"字符串返回,请指出其中的错误.
//不确定
char *GetBlue()
{
char *pcColor;
char*pcNewColor;
pcColor = “blue”;
pcNewColor =(char*)malloc(strlen(pcColor));
strcpy(pcNewColor, pcColor);
return pcNewColor;
}
答:strcpy是一个字符串拷贝的函数,它的函数原型为strcpy(char dst, ct char *src);将src开始的一段字符串拷贝到dst开始的内存中去,结束的标志符号为'0',由于拷贝的长度不是由我们控制的,所以这个字符串拷贝很容易出错
100.常见的object-c的数据类型有哪些,和C的基本数据类型有什么区别?如:NSInteger和int
答:object的数据类型由NSString,NSNumber,NSArray,NSMutableArray,NSData等等,这些都是class,创建后便是对象,而C语言的基本数据类型int,只是一定字节的内存空间,用于存放数值,NSInteger是基本的数据类型,并不是NSNumber的子类,当然也不是NSObject的子类。NSInteger是基本数据类型int或者Long的别名(NSInteger的定义typedef long NSInteger)它的区别在于,NSInteger会根据系统是32位还是64位来决定是本身int还是long.
101.iOS有垃圾回收机制吗?它是以怎样的机制来工作的?
答: OC是支持垃圾回收机制的(Garbage collection简称GC),但是apple的移动终端中,是不支持GC的,Mac桌面系统开发中是支持的.
移动终端开发是支持ARC(Automatic
Reference Counting的简称),ARC是在IOS5之后推出的新技术,它与GC的机制是不同的。我们在编写代码时,不需要向对象发送release或者autorelease方法,也不可以调用delloc方法,编译器会在合适的位置自动给用户生成release消息(autorelease),ARC的特点是自动引用技术简化了内存管理的难度.
102.请使用gcd完成如下任务,执行并发任务task1,task1完成后update UI.
答:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{
//task1:
NSLog(@"执行task1");
//更新UI
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"更新UI");
});
});
103.为什么在主线程中更新UI?子线程中想要更新UI怎么做?
答:(1)在子线程中不能更新UI,除了极少数UI外,其他UI更新要等到子线程执行完毕后回到主线程中进行更新。如果子线程一直在运行,则子线程中UI更新的函数栈主线程无法得知,即UI无法更新;
(2)回到主线程中进行UI更新;
104.简述通过Storyboard实现一个tableView
(自定义cell的关键步骤).
答:首先创建自己的自定义cell的类,我们叫做CustomCell,要继承于UITableViewCell。在这个类中定义自己所需要的控件。
然后,打开storyboard,选择自己要添加自定义cell的UIViewController,我们叫它为ViewController。在UITableView里面添加一个cell(或者修改原有的cell)。将cell的style改为custom,将cell的类改为CustomCell,将identifier改为CustomCellIdentifier。然后,可以在cell中添加控件,将控件和刚才在CustomCell中定义的控件连起来。
最后,在ViewController的UITableView的tableView:cellForRowAtIndexPath:代理方法中添加以下代码:
[plain]
CustomCell*cell=[tableViewdequeueReusableCellWithIdentifier:@"CustomCellIdentifier"];
这样,就创建了一个cell,可以在这句代码之后对自己添加的控件进行设置。
105.如何生成同时支持多个架构(simulator,arm7,arm64)的通用静态库?
答:ValidArchitectures设置为:armv7|armv7s|arm64|i386|x86_64;
Architectures设置不变(或根据你需要):armv7|arm64;
然后分别选择iOS设备和模拟器进行编译,最后找到相关的.a进行合包,使用lipo -create真机库.a的路径模拟器库.a的的路径-output合成库的名字.a;
这样就制作了一个通用的静态库.a;
106.请写出一个xml文件,用于描述一个书架,书架上有2本书,书本的类别(category)分别是cooking,children.要求tag中包含书名(title),作者(author).类别(category)要用属性表示.
答:
书名1
作者1
书名2
作者2
107.strcpy和memcpy的最大区别是什么?
答:1、复制的内容不同。strcpy只能复制字符串,而memcpy可以复制任意内容,例如字符数组、整型、结构体、类等。
2、复制的方法不同。strcpy不需要指定长度,它遇到被复制字符的串结束符"0"才结束,所以容易溢出。memcpy则是根据其第
3个参数决定复制的长度。
3、用途不同。通常在复制字符串时用strcpy,而需要复制其他类型数据时则一般用memcpy
108.g++, ld是什么?声明编译选项–DSUPPORT_BLUETOOTH =
1有什么作用?
答: g++是GNU的c++编译器;
109.@class用途
答:@class一般用于头文件中声明某个类的实例变量的时候用到.它只是声明,至于内部的实现是没有告诉编译器的.
110.delegate使用assign or retain简述理由.
答:assign,防止出现循环引用;
111.NSString与NSData之间的转换过程中要特别注意的事项是什么?
解:NSString转换成NSData对象
NSData* xmlData = [@"testdata"dataUsingEncoding:NSUTF8StringEncoding];
NSData转换成NSString对象
NSData * data;
NSString *result = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSData转换成char*
NSData *data;
char *test=[data bytes];
char*转换成NSData对象
byte tempData = malloc(sizeof(byte)16);
NSData *content=[NSData dataWithBytes:tempData length:16];
转换过程中要注意NSData的编码格式问题.
解决方法:
先设置断点然后在控制台po出NSData的变量,看看会显示什么。
如果po出的NSData是可阅读的,直接能看到文本的内容,则使用[NSString stringWithFormat:NSData] (这里的NSData指的是你需要转换成NSString的NSData变量)即可。
如果po出的NSData是不可阅读的乱码,那一般都是有编码格式的,最常用的是NSUTF8StringEncoding,另外还有NSASCIIStringEncoding等,你可以在Apple文档里找到编码格式的那个枚举类型,挨个尝试。
112.请用代码如何判断某个对象obj是否支持某个method.
解:if ([srespondsToSelector:@selector(print:)]) {
[s print:@"支持这个方法"];
}
113.请用简单的代码展示@protocol的定义及实现.
解: #warning代理第一步:声明协议
@protocol MarryMe
-(void)makeMoney;
@end
warning代理第二步:声明代理
@property(nonatomic,assign)id myDeleget;
.m文件中
warning代理第三步:代理人执行协议方法
[self.myDeleget makeMoney];
代理人.m文件中
warning代理第四步:签订协议
@interface Boy : NSObject
Girl *girl = [[Girl alloc] init];
warning代理第五步:成为代理人
girl.myDeleget = self;
[girl getMessage:message];
warning协议代理第六步:实现协议方法
-(void)makeMoney{
NSLog(@"aaa");
}
/_不是iOS的题_/114.请讲述Indesign中主页作用
115.请描述应聘岗位的未来职业规划
解:答案不唯一,如有需要请自行规划活着百度.
116.3升的杯子一个,5升的杯子一个,杯子的形状不规则,问怎么才能得到4升的水,水无限多.(请写出推理过程)
解:先将5升的杯子倒满,然后把5升的杯子中的水倒入3升的杯子,倒满后5升的杯子剩下2升.再把3升杯子中的水倒掉,把5升的杯子中剩余的2升水倒入3升的杯子中,然后把5升的杯子倒满.再用5升的杯子中的水给3升的杯子添满,则5升的杯子中剩余4升的水.
117.数据持久化存储方案有哪些?
解:所谓的持久化,就是将数据保存到硬盘中,使得在应用程序或机器重启后可以继续访问之前保存的数据。在iOS开发中,数据持久化的方案有5种方案:
plist文件(属性列表)
preference(偏好设置)
NSKeyedArchiver(归档)
SQLite 3
CoreData
118.网络通信用过哪些方式?
解: ios设备的网络通信的方法,有如下两个大类:
1、使用socket的方式进行通信。
2、使用asynsocket类库进行通信。
119.如何处理多个网络请求并发的情况?
解: //了解(并发)当有多个线程在操作时,如果系统只有一个CPU,则它根本不可能真正同时进行一个以上的线程,它只能把CPU运行时间划分成若干个时间段,再将时间段分配给各个线程执行,在一个时间段的线程代码运行时,其它线程处于挂起状。.这种方式我们称之为并发(Concurrent)。
遇到这种情况建议使用第三方的网络库。比如AFNetworking。也可以通过GCD和NSOperationQueue来控制并发
120.简单介绍一下KVC和KVO,他们都可以应用在哪些场景?
解: KVO:键值监听,观察某一属性的方法
KVC:键值编码,是一种间接访问对象的属性
121.讲述一下runtime的概念,message
send如果寻找不到响应的对象,会如何?
Objc Runtime其实是一个Runtime库,它基本上是用C和汇编写的,这个库使得C语言有了面向对象的能力。
- iOS能否嵌入其他语言?如何实现?
不会!!!!!
- iOS移动开发最终生成的是什么文件?其结构如何?
最后打包完成是一个.ipa文件可以通过iTunes和其他工具对有测试资格的手机进行安装
- UINavigationController如何要使用push/pop功能的话,需要怎么实现
1.用UINavigationController的时候用pushViewController:animated
----返回之前的视图[[selfnavigationController] popViewControllerAnimated:YES];
---ps:push以后会在navigation的left bar自动添加back按钮,它的响应方法就是返回。所以一般不需要写返回方法,点back按钮即可。
2.其他时候用presentModalViewController:animated
[selfpresentModalViewController:controller animated:YES];//YES有动画效果
-----返回之前的视图[selfdismissModalViewControllerAnimated:YES];
3.切换视图一般用不到addSubview
UINavigationController是导航控制器,如果pushViewController的话,会跳转到下一个ViewController,点返回会回到现在这个ViewController;
如果是addSubview的话,其实还是对当前的ViewController操作,只是在当前视图上面又“盖”住了一层视图,其实原来的画面在下面呢,看不到而已。
- UIView如何需要重新绘制整个界面,需要调用什么方法?
UIView setNeedsDisplay和setNeedsLayout方法。首先两个方法都是异步执行的。而setNeedsDisplay会调用自动调用drawRect方法,这样可以拿到UIGraphicsGetCurrentContext,就可以画画了。而setNeedsLayout会默认调用layoutSubViews,就可以处理子视图中的一些数据。
综上所述:setNeedsDisplay方便绘图,而layoutSubViews方便出来数据
setNeedDisplay告知视图它发生了改变,需要重新绘制自身,就相当于刷新界面.
- Plist文件?结构是?
Plist文件通常用于储存用户设置,也可以用于存储捆绑的信息,该功能在旧式的Mac OS中是由资源分支提供的。
Plist主要有Core Fundation类型构成,也可以将这些类型放入NSDictionary和NSArray以便后塍更复杂的数据类型
- iOS里面的二进制数据类型是什么?和NSString如何互相转换?
NSData:用于存储二进制的数据类型
NSData类提供了一种简单的方式,它用来设置缓冲区、将文件的内容读入缓冲区,或将缓冲区的内容写到一个文件。
不变缓冲区(NSData类),也可定义可变的缓冲区(NSMutableData类)。
NSData、NSString互转:
NSData * data = [str dataUsingEncoding:NSUTF8StringEncoding];
//NSString转换成NSData类型
NSString * newStr = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
- iOS里面是否有GBK的字符编码描述?即NSUTF8StringEncoding如果有,是怎样的?
不会
- iOS里面的手势是如何实现的?
130.谈谈你了解的设计模式,你用过哪些,他们的缺点
1.MVC:优点:
1、开发人员可以只关注整个结构中的其中某一层;
2、可以很容易的用新的实现来替换原有层次的实现;
3、可以降低层与层之间的依赖;
4、有利于标准化;
5、利于各层逻辑的复用。
缺点:
1、降低了系统的性能。这是不言而喻的。如果不采用分层式结构,很多业务可以直接造访数据库,以此获取相应的数据,如今却必须通过中间层来完成。
2、有时会导致级联的修改。这种修改尤其体现在自上而下的方向。如果在表示层中需要增加一个功能,为保证其设计符合分层式结构,可能需要在相应的业务逻辑层和数据访问层中都增加相应的代码。
2.观察者模式优点:
1、观察者模式在被观察者和观察者之间建立一个抽象的耦合。被观察者角色所知道的只是一个具体观察者列表,每一个具体观察者都符合一个抽象观察者的接口。被观察者并不认识任何一个具体观察者,它只知道它们都有一个共同的接口。
由于被观察者和观察者没有紧密地耦合在一起,因此它们可以属于不同的抽象化层次。如果被观察者和观察者都被扔到一起,那么这个对象必然跨越抽象化和具体化层次。
2、观察者模式支持广播通讯。被观察者会向所有的登记过的观察者发出通知,
观察者模式缺点:
1、如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。
2、如果在被观察者之间有循环依赖的话,被观察者会触发它们之间进行循环调用,导致系统崩溃。在使用观察者模式是要特别注意这一点。
3、如果对观察者的通知是通过另外的线程进行异步投递的话,系统必须保证投递是以自恰的方式进行的。
4、虽然观察者模式可以随时使观察者知道所观察的对象发生了变化,但是观察者模式没有相应的机制使观察者知道所观察的对象是怎么发生变化的。
3.单例模式:主要优点:
1、提供了对唯一实例的受控访问。
2、由于在系统内存中只存在一个对象,因此可以节约系统资源,对于一些需要频繁创建和销毁的对象单例模式无疑可以提高系统的性能。
3、允许可变数目的实例。
3.单例模式:主要缺点:
1、由于单利模式中没有抽象层,因此单例类的扩展有很大的困难。
2、单例类的职责过重,在一定程度上违背了“单一职责原则”。
3、滥用单例将带来一些负面问题,如为了节省资源将数据库连接池对象设计为的单例类,可能会导致共享连接池对象的程序过多而出现连接池溢出;如果实例化的对象长时间不被利用,系统会认为是垃圾而被回收,这将导致对象状态的丢失.
131.数据持久化存储方案有哪些?
答:
(附网址:http://www.cocoachina.com/industry/20130328/5908.html)
iOS中的数据持久化方式,基本上有以下四种:属性列表、对象归档、SQLite3和Core Data
1.属性列表(NSUserDefaults,用于存储配置信息)
涉及到的主要类:NSUserDefaults,一般[NSUserDefaults standardUserDefaults]就够用了
2.对象归档
要使用对象归档,对象必须实现NSCoding协议.大部分Object C对象都符合NSCoding协议,也可以在自定义对象中实现NSCoding协议,要实现NSCoding协议,实现两个方法
3.SQLite3
SQLite的数据库权限只依赖于文件系统,没有用户帐户的概念。SQLite有数据库级锁定,没有网络服务器。它需要的内存,其它开销很小,适合用于嵌入式设备。你需要做的仅仅是把它正确的编译到你的程序。
4.Core Data
Core Data本质上是使用SQLite保存数据,但是它不需要编写任何SQL语句。
要使用Core Data,需要在Xcode中的数据模型编辑器中设计好各个实体以及定义好他们的属性和关系。之后,通过操作这些对象,结合Core Data完成数据的持久化:
132.网络通信用过哪些方式?
(附网址:http://blog.csdn.net/chang6520/article/details/7967698)
同样也是代码解释
iOS设备的网络通信的方法,有如下两个大类:
1、使用socket的方式进行通信。
以TCP为利,对于TCP来说,是要区分服务端和客户端的。服务端:通常的方法是服务端启动后监听,是否有客户端连接,如果有连接,则建立与客户端的通信。客户端的方法通常是连接服务端,当连接成功之后,就希望发送数据了。
2、使用asynsocket类库进行通信。
133.如何处理多个网络请求并发的情况?
答:
(附网址:http://www.cnblogs.com/yanhuaxuanlan/p/4683557.html)
答案都是代码,大家可以打开网址仔细阅读
1.并发当有多个线程在操作时,如果系统只有一个CPU,则它根本不可能真正同时进行一个以上的线程,它只能把CPU运行时间划分成若干个时间段,再将时间段分配给各个线程执行,在一个时间段的线程代码运行时,其它线程处于挂起状。.这种方式我们称之为并发(Concurrent)。
2.并行当系统有一个以上CPU时,则线程的操作有可能非并发。当一个CPU执行一个线程时,另一个CPU可以执行另一个线程,两个线程互不抢占CPU资源,可以同时进行,这种方式我们称之为并行(Parallel)。
3.区别并发和并行是即相似又有区别的两个概念,并行是指两个或者多个事件在同一时刻发生;而并发是指两个或多个事件在同一时间间隔内发生。
134.简单介绍一下KVC和KVO,他们都可以应用在哪些场景?
答:
(附网址:http://blog.csdn.net/zhaozy55555/article/details/8598374
http://www.cnblogs.com/kenshincui/p/3871178.html)
KVC:NSKeyValueCoding的简称,是一种可以直接通过字符串的名字(key)来访问类属性的机制,而不是通过调用的Setter、Getter方法访问。
KVC的操作方法由NSKeyValueCoding协议提供,NSObject就实现了这个协议,也就是说如果对象是NSObject的子对象那么就支持KVC操作,KVC有两种操作方法,一种是设值,一种是取值,可以理解为getter和setter,不过稍微有所不同的是,设置对象值的方法中有两个,setValue:属性值forKey:属性名(一般的设置,比如说是说设置NSString,NSNumber等基本类类型,setetValue:属性值forKeyPath:属性路径
2.KVO:NSKeyValueObserving的简称,当指定的对象的属性被修改了,允许对象接受到通知的机制。每次指定的被观察对象的属性被修改的时候,KVO都会自动的去通知相应的观察者,相当于设计模式中的观察者模式。
Key-Value Observing (KVO)建立在KVC之上,能够观察一个对象的KVC key path值的变化,接下来的做的实例是在iOS中视图的ViewDidLoad中实现的,跟KVC类似,不过可以监听值的变化,实现起来很简单addObserver添加观察,observeValueForKeyPath观察变化之后的事件,最后需要销毁以下监听事件,
135.实现多线程有哪些方法,分别有什么区别?
答: (http://www.cnblogs.com/hanjun/p/3667874.html)
1.NSThread
2.NSOperationQueue
3.GCD
区别:
Thread是这三种范式里面相对轻量级的,但也是使用起来最负责的,你需要自己管理thread的生命周期,线程之间的同步。线程共享同一应用程序的部分内存空间,它们拥有对数据相同的访问权限。你得协调多个线程对同一数据的访问,一般做法是在访问之前加锁,这会导致一定的性能开销。在iOS中我们可以使用多种形式的thread:
Cocoa threads:使用NSThread或直接从NSObject的类方法performSelectorInBackground:withObject:来创建一个线程。如果你选择thread来实现多线程,那么NSThread就是官方推荐优先选用的方式。
Cocoa operations是基于Obective-C实现的,类NSOperation以面向对象的方式封装了用户需要执行的操作,我们只要聚焦于我们需要做的事情,而不必太操心线程的管理,同步等事情,因为NSOperation已经为我们封装了这些事情。NSOperation是一个抽象基类,我们必须使用它的子类。iOS提供了两种默认实现:NSInvocationOperation和NSBlockOperation。
Grand Central Dispatch (GCD): iOS4才开始支持,它提供了一些新的特性,以及运行库来支持多核并行编程,它的关注点更高:如何在多个cpu上提升效率。
136.The ios/osx’s graphics is bassed onOpenGL . what is OpenGL?
iOS的/ OS X的图形是基于OpenGL。什么是OpenGL?
(附网址:https://developer.apple.com/opengl/)
官方的解释:OpenGL是硬件基础图形加速在OS X的权力核心动画,核心形象,和石英的极端和给你的应用程序访问惊人的3D图形处理能力。使用工业标准的图形API创建一系列应用程序,包括游戏,动画制作软件,以及医疗成像解决方案。
百度的解释:
OpenGL:(Open Graphics Library)是指定义了一个跨编程语言、跨平台的编程接口规格的专业的图形程序接口。它用于三维图像(二维的亦可),是一个功能强大,调用方便的底层图形库。计算机三维图形是指将用数据描述的三维空间通过计算转换成二维图像并显示或打印出来的技术。OpenGL就是支持这种转换的程序库,它源于SGI公司为其图形工作站开发的IRIS GL,在跨平台移植过程中发展成为OpenGL。OpenGL被设计成独立于硬件、独立于窗口系统,在各种操作系统的计算机上都可用的,并能在网络环境下以客户/服务器模式工作,是专业图形处理、科学计算等高端应用领域的标准图形库