iOS中OC面试题整理(一)
1、static关键字的作用:
1)函数体内static变量的作用范围为该函数体,不同于auto变量,该变量的内存只被分配一次,因此其值在下次调用时仍维持上次的值;
2)在模块内的static全局变量可以被模块内所用函数访问,但不能被模块外其他函数访问;
3)在模块内的static函数只可被这一模块内的其他函数调用,这个函数的使用范围被限制在声明他的模块内;
4)在类中的static成员变量属于整个类所拥有,对类的所有对象只有一份拷贝;
5)在类中的static成员函数属于整个类所拥有,这个函数不接收this指针,因此只能访问类的static成员变量。
2、线程与进程的区别和联系:
进程和线程都是由操作系统所提供的程序运行的基本单元,系统利用该基本单元实现系统对应用的并发性。进程和线程的主要差别在于它们是不同的操作系统资源管理方式。进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其他进程产生影响,而线程之间没有独立的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多进程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。
3、堆和栈的区别和联系:
管理方式:对于栈来讲,是由编译器自动管理,无需我们手工控制;对于堆来说,释放工作由程序员控制,容易产生memory leak。
申请大小:
栈:在windows下,栈是向低地址扩展的数据结构,是一块连续的内存的区域。这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的,在windows下,栈的大小是2M,如果申请的空间超过栈的剩余空间时,将提示overflow。因此,能从栈获得的空间较小。
堆:堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得空间比较灵活,也比较大。
碎片问题:对于堆来讲,频繁的new/delete势必会造成内存空间的不连续,从而造成大量的碎片,使程序效率降低。对于栈来讲,则不会存在这个问题,因为栈是先进后出的队列,他们是如此的一一对应,以至于永远都不可能有一个内存块从栈中弹出。
分配方式:堆都是动态分配的,没有静态分配的堆。栈有两种分配方式:静态分配和动态分配。静态分配是编译器完成的,比如局部变量的分配。动态分配由alloca函数进行分配,但是栈的动态分配和堆是不同的,他的动态分配是由编译器进行释放,无需我们手工实现。
分配效率:栈是机器系统提供的数据结构,计算机会在底层对栈提供支持:分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行,这就决定了栈的效率比较高。堆则是C/C++函数库提供它的机制是很复杂的。
4、自动释放池是什么,如何工作:
当向一个对象发送autorelease消息时,Cocoa就会将该对象的一个引用放入到最新的自动释放池他仍然是个正当的对象,因此自动释放池定义的作用域内的其他对象可以向它发送消息。当程序执行到作用域结束的位置时,自动释放池就会被释放,池中的所有对象也就被释放。
1)objc-c是通过引用计数的方式管理内存的,对象在开始分配内存的时候引用计数为1,以后每当碰到有copy,retain的时候引用计数都会加1,每当碰到release和autorelease的时候引用计数就会减1,如果此对象的计数变为0,就会被系统销毁。
2)NSAutoreleasePool就是用来做引用计数的管理工作的,这个东西一般不用管。
3)autorelease和release没什么区别,只是引用计数减1的时机不同而已,autorelease会在对象的使用真正结束的时候才做引用计数减1.
5、什么是动态绑定:
在运行时确定要调用的方法,动态绑定将调用方法的确定也推迟到运行时。在编译时,方法的调用并不和代码绑定在一起,只有在消息发送出来之后,才确定被调用的代码。通过动态类型和动态绑定技术,代码每次执行都可以得到不同的结果。运行时因子负责确定消息的接收者和被调用的方法。运行时的消息分发机制为动态绑定提供支持。当您向一个动态类型确定了的对象发送消息时,运行环境系统会通过接收者的isa指针定位对象的类,并以此为起点确定被调用的方法,方法和消息是动态绑定的。而且,您不必在代码中做任何工作,就可以自动获取动态绑定的好处。每次发送消息时,特别是当消息的接收者是动态类型已经确定的对象时,动态绑定就会例行而透明地发生。
6、block相关概念
1)block是什么? block是一个仿制对象 在OC中,类都是继承NSObject,NSObject里面都会有isa,是一个objc_class 指针 而block的对象,在clang的C++重写。
1 ^int(){printf("val"); return 111;};
block会转化为
1 struct __block_impl { 2 void *isa; 3 int Flags; 4 int Reserved; 5 void *FuncPtr; 6 }; 7 8 struct __testBlock_block_impl_0 { 9 struct __block_impl impl; 10 struct __testBlock_block_desc_0* Desc; 11 __testBlock_block_impl_0(void *fp, struct __testBlock_block_desc_0 *desc, int flags=0) { 12 impl.isa = &_NSConcreteStackBlock; 13 impl.Flags = flags; 14 impl.FuncPtr = fp; 15 Desc = desc; 16 } 17 };
2)block对象的生存周期 对象都是在堆上声明

浙公网安备 33010602011771号