iOS 面试题
1.#import和#include的区别 @class?
@class一般用于头文件中需要声明该类的某个实例变量的时候用到,在m文 件中还是需要使用#import
而#import比起#include的好处就是不会引起交叉编译
2. readwrite,readonly,assign,retain,copy,nonatomic 属性的作用
2. readwrite,readonly,assign,retain,copy,nonatomic 属性的作用
@property是 一个属性访问声明,扩号内支持以下几个属性: 1,getter=getname,setter=setname,设置setter与 getter的方法名2,readwrite,readonly,设置可供访问级别3,assign,setter方法直接赋值,不进行任何retain操作,为了解决原类型与环循引用问题4,retain,setter方法对参数进行release旧值再retain新值,所有 实现都是这个顺序(cc上有相关资料)5,copy,setter方法进行copy操作,与retain处理流程一样,先旧值release,再 copy出新的对象,retaincount为1。这是为了减少对上下文的依赖而引入的机制。6,nonatomic,非原子性访问,不加同步, 多线程并发访问会提高性能。注意,如果不加此属性,则默认是两个访问方法都为原子型事务访问。锁被加到所属对象实例级(我是这么理解的…)。
3.在一个对象的方法里面:self.name= “object”;和 name =”object” 有什么不同吗?
3.在一个对象的方法里面:self.name= “object”;和 name =”object” 有什么不同吗?
self.name =”object”:会调用对象的setname()方法;name = “object”:会直接把object赋值给当前对象的name属性。
4.请简述self.name= nil的机制,以及与[namerelease]的区别?
4.请简述self.name= nil的机制,以及与[namerelease]的区别?
self.name =nil;
//使用nil参数调用setname:方法
[name release] 生成的访问器将自动释放以前的name对象
5.请简要说明viewdidload和viewdidunload何时调用
5.请简要说明viewdidload和viewdidunload何时调用
viewdidload在view从nib文件初始化时调用loadview在controller的view为nil时调用。
此方法在实现view时调用,view控制器默认会注册memory warning notification,当view controller的任何view没有用的时候,
viewdidunload会被调用,在这里实现将retain的view release,如果是retain的iboutlet view 属性则不要在这里release,iboutlet会负责release 。
控制器view的生命周期:
首先判断控制器是否有视图,如果没有就调用loadview方法创建:通过storyboard或者代码
随后调用viewdidload,可以进行下一步的初始化操作;只会被调用一次
在视图显示之前调用viewwillappear;该函数可以多次调用视图viewdidappear在视图显示之前调用viewwilldisappear;该函数可以多次调用(如需要)在布局变化前后,调用viewwill/didlayoutsubviews处理相关信息
6.实例化一个uitableview对象,要求写出关键语句?
6.实例化一个uitableview对象,要求写出关键语句?
uitableview *my = [[uitableview alloc]initwithframe:<(cgrect)frame> style:<(uitableviewstyle)style>]; my.delegate = self; my.datasource = self;
首先需要分配空间设置表格类型
然后需要设置两个必须的委托对象。
7.使用sql语句查询出省名以湖开头,邮编为436001所在的市区?(表名及字段名自定义)
7.使用sql语句查询出省名以湖开头,邮编为436001所在的市区?(表名及字段名自定义)
select*fromcitys where postcode=436001 and province=’湖%’;
8.打印结果
8.打印结果
main() { int a[5]={1,2,3,4,5}; int *ptr=(int *)(&a+1); printf(“%d,%d”,*(a+1),*(ptr-1)); }
2,5(a+1)就是a[1],(ptr-1)就是a[4],执行结果是2,5 &a+1不是首地址+1,会认为加一个a数组的偏 移,是偏移了一个数组的大小(本例是5个int)int ptr=(int )(&a+1);则ptr实际 是&(a[5]),也就是a+5原因如下: &a是数组指针,其类型为 int ( * )[5];而 指针加1要根据指针类型加上一定的值,不同类型的指针+1之后增加的大小不同。a是长度为5的int数组指针,所以要加 5*sizeof(int)所以ptr实际是a[5]但是prt与(&a+1)类型是不一样的(这点很重要)所以prt-1只会减去sizeof(int*)
a,&a的地址是一样的但意思不一样 a是数组首地址也就是a[0]的地址&a是对象(数组)首地址a+1是数组下一元素的地址即a[1],&a+1是下一个对象的地址,即a[5].
void func ( char str[100] ) { sizeof(str ) = ? } void *p = malloc( 100 ); sizeof( p ) = ?
这题 很常见了,func ( char str[100] )函数中数组名作为函数形参时,在函数体内,数组名失去了本身的内涵,仅仅只是一个指针;在失去其内涵的同时,它还失去了其常量特性,可以作自增、自减等操作,可以被修改。windows nt 32位平台下,指针的长度(占用内存的大小)为4字节,故sizeof( str ) 、sizeof( p ) 都为4。
9.用预处理指令#define声明一个常数,用以表明1年中有多少秒(忽略闰年问题)
9.用预处理指令#define声明一个常数,用以表明1年中有多少秒(忽略闰年问题)
defineseconds_per_year (60 * 60 * 24 * 365)ul
我在这想看到几件事情:
#define 语法的基本知识(例如:不能以分号结束,括号的使用,等等)
懂得预处理器将为你计算常数表达式的值,因此,直接写出你是如何计算一年中有多少秒而不是计算出实际的值,是更清晰而没有代价的。
意识到这个表达式将使一个16位机的整型数溢出-因此要用到长整型符号l,告诉编译器这个常数是的长整型数。
如果你在你的表达式中用到ul(表示无符号长整型),那么你有了一个好的起点。记住,第一印象很重要。
10.写一” 标准”宏min ,这个宏输入两个参数并返回较小的一个
10.写一” 标准”宏min ,这个宏输入两个参数并返回较小的一个
#define min(a,b)((a) <= (b) ? (a) : (b))这个测试是为下面的目的而设的:
标识#define在宏中应用的基本知识。这是很重要的,因为直到嵌入(inline)操作符变为标准c的一部分,宏是方便产生嵌入代码的唯一方
法,对于嵌入式系统来说,为了能达到要求的性能,嵌入代码经常是必须的方法。三重条件操作符的知识。这个操作符存在c语言中的原因是它使得编译器能产生比 if-then-else 更优化的代码,了解这个用法是很重要的。 懂得在宏中小心地把参数用括号括起来 我也用这个问题开始讨论宏的副作用 例如:当你写下面的代码时会发生什么事?least = min(*p++, b);结果是:
((*p++) <= (b) ? (*p++) :(*p++))
这个表达式会产生副作用,指针p会作三次++自增操作。
11.数组和指针的区别
11.数组和指针的区别
数组可以申请在栈区和数据区;指针可以指向任意类型的内存块sizeof作用于数组时,得到的是数组所占的内存大小;作用于指针时,得到的都是4个字节的大小数组名表示数组首地址,值不可以改变,如不可以将++作用于数组名上;普通指针的值可以改变,如可将++作用于指针上用字符串初始化字符数组是将字符串的内容拷贝到字符数组中;用字符串初始化字符指针是将字符串的首地址赋给指针,也就是指针指向了该数组
12.static的作用
12.static的作用
函数体内static 变量的作用范围为该函数体,不同于 auto 变量,该变量的内存只被分配一次,
因此其值在下次调用时仍维持上次的值;在模块内的static 全局变量可以被模块内所用函数访问,但不能被模块外其它函数访问;在模块内的static函数只可被这一模块内的其它函数调用,这个函数的使用范围被限制在声明它的模块内;在类中的static成员变量属于整个类所拥有,对类的所有对象只有一份拷贝;在类中的static 成员函数属于整个类所拥有,这个函数不接收 this 指针,因而只能访问类的static 成员变量。
13.简述内存分区情况
13.简述内存分区情况
代码区:存放函数二进制代码数据区:系统运行时申请内存并初始化,系统退出时由系统释放。存放全局变量、静态变量、常量堆区:通过malloc等函数或new等操作符动态申请得到,需程序员手动申请和释放栈区:函数模块内申请,函数结束时由系统自动释放。存放局部变量、函数参数
14.#include和#include”filename”有什么区别
14.#include和#include”filename”有什么区别
#include直接在库文件目录中搜索所包含的文件;#include”filename”在当前目录下搜索所包含的文件,如果没有的话再到库文件目录搜索。
15.const char * p; char const * p; char * const p; const char * const p;
四个修饰指针有什么区别
(1)定义了一个指向不可变的字符串的字符指针(2)和(1)一样(3)定义了一个指向字符串的指针,该指针值不可改变,即不可改变指向(4)定义了一个指向不可变的字符串的字符指针,且该指针也不可改变指向
16.mvc的理解?
mvc模式考虑三种对象: 模型对象 model视图对象 view控制器对象。controller 模型对象负责应用程序的数据和定义操作数据的逻辑;视图对象知道如何显示应用程序的模型数据;控制器对象是m与v之间的协调者。
17.在obj-c中有没有私有方法?私有变量?一般采用什么方法实现?
objective-c – 类里面的方法只有两种, 静态方法和实例方法.这似乎就不是完整的面向对象了,按照oo的原则就是一个对象只暴露 有用的东西.如果没有了私有方法的话,对于一些小范围的代码重用就不那么顺手了. 在类里面声名一个私有方法
@interfacecontroller : nsobject { nsstring *something; }
+(void)thisisastaticmethod;
-(void)thisisaninstancemethod;
@end
@interfacecontroller (private)
-(void)thisisaprivatemethod;
@end
@private可以用来修饰私有变量
在objective‐c中,所有实例变量默认都是私有的,所有实例方法默认都是公有的
18.oc中加号方法与减号的区别?
加号方法是类方法,属于静态方法减号方法是实例方法必须由类的实例来调用
19.free与release的区别
20.在终端环境下,分别说明4,2,1,0对应的权限是什么
linux系统下文件的权限由三位二进制数表示,从左到右依次表示读、写、可执行。0表示不行,1表示行。4对应2进制的100,就是可读不可写不可执行。
21.arc机制
arc就是automatic reference counting ,简单说就是就是代码中自动加入了retain/release,原先需要手动添加的用来处理内存管理的引用计数的代码可以自动地由编译器完成了。
使用arc的好处
使用arc有什么好处呢?
看到上面的例子,大家就知道了,以后写objective-c的代码变得简单多了,因为我们不需要担心烦人的内存管理,担心内存泄露了,代码的总量变少了,看上去清爽了不少,也节省了劳动力
代码高速化,由于使用编译器管理引用计数,减少了低效代码的可能性不好的地方
记住一堆新的arc规则—关键字及特性等需要一定的学习周期
一些旧的代码,第三方代码使用的时候比较麻烦;修改代码需要工数,要么修改编译开关
22.自动释放池是什么,如何工作
当向一个对象发送一个autorelease 消息时,cocoa就会将该对象的一个引用放入到最新的自动释放池。它仍然是个正当的对象,因此自动释放池定义的作用域内的其它对象可以向它发送消息。当程序执行到作用域结束的位置时,自动释放池就会被释放,池中的所有对象也就被释放。 ojc-c 是 通过一种referring counting(引用计数)的方式来管理内存的, 对象在开始分配内存(alloc)的时候引用计数为一,以后每当碰到有copy,retain的时候引用计数都会加一, 每当碰到release和autorelease的时候引用计数就会减一,如果此对象的计数变为了0, 就会被系统销毁.nsautoreleasepool 就是用来做引用计数的管理工作的,这个东西一般不用你管的.autorelease和release没什么区别,只是引用计数减一的时机不同而已,autorelease会在对象的使用真正结束的时候才做引用计数减一.
23.浅复制和深复制的区别?//浅拷贝和深拷贝
浅层复制(copy):只复制指向对象的指针,而不复制引用对象本身。//通过对象的指针来访问这个对象深层复制(mutablecopy):复制引用对象本身 意思就是有个a对象,复制一份后得到a_copy对象后,对于浅复制来说,a和a_copy指向的是同一个内存资源,复制的只不过是是一个指针,对象本身资源 还是只有一份,那如果我们对a_copy执行了修改操作,那么发现a引用的对象同样被修改,这其实违背了我们复制拷贝的一个思想。深复制就好理解了,内存中存在了 两份独立对象本身。//当修改a时,a copy不变。
25.frame和bounds有什么不同?
frame指的是:该view在父view坐标系统中的位置和大小。(参照点是父亲的坐标系统)//frame:框架、结构bounds指的是:该view在本身坐标系统中 的位置和大小。(参照点是本身坐标系统)//bounds:界限
26. obj-c的优缺点
优点: cateogiesposing动态识别指标计算弹性讯息传递不是一个过度复杂的 c 衍生语言objective-c 与 c++ 可混合编程 缺点: 不支援命名空间不支持运算符重载不支持多重继承使用动态运行时类型,所有的方法都是函数调用,所以很多编译时优化方法都用不到。(如内联函数等),性能低劣。
27.用变量a给出下面的定义
a)一个整型数(an integer)
b)一个指向整型数的指针( a pointer to aninteger)
c)一个指向指针的的指针,它指向的指针是指向一个整型数( apointer to a pointer to an intege)r
d)一个有10个整型数的数组( an array of 10 integers)
e) 一个有10个指针的数组,该指针是指向一个整型数的。(an array of 10 pointers to integers)
f) 一个指向有10个整型数数组的指针( a pointer to an array of 10 integers)
g) 一个指向函数的指针,该函数有一个整型参数并返回一个整型数(apointer to a function that takes an integer as an argument
andreturns an integer)
h)一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型数( an array of ten pointers to functions t
hat takean integer argument and return an integer )
a) int a; // aninteger
b) int *a; // a pointer to aninteger
c) int **a; // a pointer to apointer to an integer
d) int a[10]; // an array of10 integers
e) int *a[10]; // an array of10 pointers to integers
f) int (*a)[10]; // a pointerto an array of 10 integers
g) int (*a)(int); // a pointerto a function a that takes an integer argument and returns aninteger
h) int (*a[10])(int); // anarray of 10 pointers to functions that take an integer argument andreturn an integer
28.写出几个死循环?
29.队列和栈有什么区别:
队列和栈是两种不同的数据容器。从”数据结构”的角度看,它们都是线性结构,即数据元素之间的关系相同。 队列是一种先进先出的数据结构,它在两端进行操作,一端进行入队列操作,一端进行出列队操作。栈是一种先进后出的数据结构,它只能在栈顶进行操作,入栈和出栈都在栈顶操作。
30.http协议中,post和get的区别是什么?
1.get方法 get方法提交数据不安全,数据置于请求行,客户端地址栏可见;get方法提交的数据大小有限get方法不可以设置书签 2.post方法 post方法提交数据安全,数据置于消息主体内,客户端不可见post方法提交的数据大小没有限制post方法可以设置书签
31. ios的系统架构分为
(核心操作系统层thecore os layer)(核心服务层thecore services layer)(媒体层themedia layer)(cocoa界面服务层the cocoa touch layer)四个层次。
32. 控件主要响应3种事件:
(基于触摸的事件)(基于值的事件)(基于编辑的事件)。
33.xib文件的构成分为哪3个图标?都具有什么功能。
file’s owner是所有nib文件中的每个图标,它表示从磁盘加载nib文件的对象;first responder就是用户当前正在与之交互的对象;view显示用户界面;完成用户交互;是uiview类或其子类。
34. 简述视图控件器的生命周期。
loadview尽管不直接调用该方法,如多手动创建自己的视图,那么应该覆盖这个方法并将它们赋值给试图控制器的view属性。
viewdidload只有在视图控制器将其视图载入到内存之后才调用该方法,这是执行任何其他初始化操作的入口。
viewvillappear当试图将要添加到窗口中并且还不可见的时候或者上层视图移出图层后本视图变成*视图时调用该方法,用于执行诸如改变视图方向等的操作。实现该方法时确保调用[super viewwillappear:].
viewdidappear当视图添加到窗口中以后或者上层视图移出图层后本视图变成*视图时调用,用于放置那些需要在视图显示后执行的代码。确保调用[super viewdidappear:]。viewdidunload当试图控制器从内存释放自己的方法的时候调用,用于清楚那些可能已经在试图控制器中创建的对象。
35. 动画有基本类型有哪几种;表视图有哪几种基本样式?
动画有两种基本类型: 隐式动画显式动画。
36. 实现简单的表格显示需要设置uitableview的什么属性、实现什么协议?
实现简单的表格显示需要设置uitableview 的 datasource 和 delegate 属性,实现uitableviewdatasource 和 uitableviewdelegate 协议。
37. cocoa touch提供了哪几种core animation过渡类型(10分)?
cocoa touch 提供了 4 种 core animation 过渡类型,分别为: 交叉淡化推挤显示覆盖
38. uiview与clayer有什么区别?
uiview 是 ios 系统中界面元素的基础,所有的界面元素都是继承自它。它本身完全是由 coreanimation 来实现的。它真正的绘图部分,是由一个 calayer 类来管理。 uiview 本身更像是一个 calayer 的管理器,访问它的跟绘图和跟坐标有关的属性。uiview 有个重要属性 layer ,可以返回它的主 calayer 实例。uiview 的 calayer 类似 uiview 的子 view 树形结构,也可以向它的 layer 上添加子layer ,来完成某些特殊的表示。即 calayer 层是可以嵌套的。uiview 的 layer 树形在系统内部,被维护着三份 copy 。分别是逻辑树,这里是代码可以操纵的;动画树,是一个中间层,系统就在这一层上更改属性,进行各种渲染操作;显示树,其内容就是当前正被显示在屏幕上得内容。动画的运作:对 uiview 的 sublayer (非主 layer )属性进行更改,系统将自动进行动画生成,动画持续时间的缺省值似乎是 0.5 秒。坐标系统: calayer 的坐标系统比 uiview 多了一个 anchorpoint 属性,使用cgpoint 结构表示,值域是 0~1 ,是个比例值。这个点是各种图形变换的坐标原点,同时会更改 layer 的 position 的位置,它的缺省值是 {0.5,0.5} ,即在 layer 的*。渲染:当更新层,改变不能立即显示在屏幕上。当所有的层都准备好时,可以调用setneedsdisplay 方法来重绘显示。变换:要在一个层中添加一个 3d 或仿射变换,可以分别设置层的 transform 或affinetransform 属性。变形: quartz core 的渲染能力,使二维图像可以被*操纵,就好像是三维的。图像可以在一个三维坐标系中以任意角度被旋转,缩放和倾斜。 catransform3d 的一套方法提供了一些魔术般的变换效果。
39.链表翻转。
40. 链表逆序(c语言)。
链表逆序就是把一个链表按照原来的链接顺序逆序实现(也就是将头变成尾,尾变成头)。
编程思路:其实最关键的是先通过原来的链接顺序找到下个节点,然后再把前个节点反序。
41. quatrz 2d的绘图功能的三个核心概念是什么并简述其作用(10分)。
上下文:主要用于描述图形写入哪里;路径:是在图层上绘制的内容;状态:用于保存配置变换的值、填充和轮廓, alpha 值等。
42. iphone os主要提供了几种播放音频的方法(10分)?
systemsound servicesavaudioplayer 类audio queue servicesopenal
43. 使用avaudioplayer类调用哪个框架、使用步骤(10分)?
avfoundation.framework 步骤: 配置 avaudioplayer 对象;实现 avaudioplayer 类的委托方法;控制 avaudioplayer 类的对象;监控音量水平;回放进度和拖拽播放。
44. 有哪几种手势通知方法、写清楚方法名?
-(void)touchesbegan:(nsset*)touchedwithevent:(uievent*)event;
-(void)touchesmoved:(nsset*)touched withevent:(uievent*)event;
-(void)touchesended:(nsset*)touchedwithevent:(uievent*)event;
-(void)touchescanceled:(nsset*)touchedwithevent:(uievent*)event;
45. 实例化一个uitableview对象,要求写出关键语句。
uitableview *my = [[uitableview alloc]initwithframe:<(cgrect)frame> style:<(uitableviewstyle)style>];
my.delegate = self;
my.datasource = self;
首先需要分配空间设置表格类型然后需要设置两个必须的委托对象。
46. cfsocket使用有哪几个步骤(10分)。
创建 socket 的上下文;创建 socket ;配置要访问的服务器信息;封装服务器信息;连接服务器;
47. core foundation中提供了哪几种操作socket的方法?
cfnetwork cfsocket bsd socket 。
48. 解析xml文件有哪几种方式(10分)?
以 dom 方式解析 xml 文件以 sax 方式解析 xml 文件;
49. 自定义一个委托(15分)。
@protocol simpleprotocol
-(void)dosomething:(nsstring*)str;
@end
@interfacesimpleclass:nsobject< simpleprotocol >{
}
@end
@implementationsimpleclass
-(void)dosomething:(nsstring *)str
{
nslog(str);
}
@end
50. 类别的作用?继承和类别在实现中有何区别?
category 可以在不获悉,不改变原来代码的情况下往里面添加新的方法,只能添加,不能删除修改。 并且如果类别和原来类中的方法产生名称冲突,则类别将覆盖原来的方法,因为类别具有更高的优先级。 类别主要有 3 个作用: (1) 将类的实现分散到多个不同文件或多个不同框架中。 (2) 创建对私有方法的前向引用。 (3) 向对象添加非正式协议。 继承可以增加,修改方法,并且可以增加属性。