iOS面试汇总

来源:互联网 发布:电视机品牌排行榜知乎 编辑:程序博客网 时间:2024/06/11 21:18
1. #import跟#include的区别,@class呢? #import<> 跟 #import""又什么区别?

       #import功能与include基本相同,不过它避免了重复引用的问题(class A,class B都引用了class C,class D若引用class A与class B,就会报重复引用的错误)。所以在OC中我们基本用的都是import。
       #import<>用于对系统文件的引用,编译器会在系统文件目录下去查找该文件。
#import"xx.h"用于对用户自定义的文件的引用,编译器首先会去用户目录下查找,然后去安装目录,最后去系统目录查找。
      @class就是告诉编译器有这个类存在,但是类是如何实现的不用告诉编译器.若.m文件用到了这个类,还是要在.m文件汇总import这个类的。
      既然这样,为什么不直接在头文件中import呢,举个例子:
      class A引用了class B,class B引用了class C.... , class A,B,C...的头文件又import了很多文件,那么 import了A的话,编译器就需要编译大量的文件,编译时间就会增加。 
      难道头文件中都是用@class吗?当然不是,有时也是需要#import的,那么什么时候该用什么呢?
(1)一般如果有继承关系的用#import,如B是A的子类那么在B中声明A时用#import;
(2) 另外就是如果有循环依赖关系,如:A->B,B->A这样相互依赖时,如果在两个文件的头文件中用#import分别声明对方,那么就会出现头文件循环利用的错误,这时在头文件中用@class声明就不会出错;
(3)还有就是自定义代理的时候,如果在头文件中想声明代理的话如

@interface SecondViewController:UIViewController

时应用#import不然的话会出错误,注意XXXDelegate是自定义的。

2. Objective-C的内存管理方式, NSAutoreleasePool的作用?

       NSAutoreleasePool是用于管理iphone应用的生命周期内所有的自动释放对象。当应用程序中有自动对象创建时,该对象就会被加入到该自动释放池。当应用程序结束时,该池会释放池中全部的自动释放对象[pool release];
       在 Objective-C中每个对象都对应着他们自己的持有计数(Retain Count),持有计数可以理解为一个整数计数器,当使用alloc方法创建对象的时候,持有计数会自动设置为1。当你向一个对象发送retain消息 时,持有计数数值会增加。相反,当你像一个对象发送release消息时,持有计数数值会减小。当对象的持有计数变为0的时候,对象会释放自己所占用的内存。

3. 为什么很多内置类如UITableViewController的delegate属性都是assign而不是retain?

       如果是retain会引起循环引用。所有的引用计数系统,都存在循环引用的问题。例如下面的引用关系:

       对象A创建并引用了对象B

       对象B创建并引用了对象C

       对象C创建并引用了对象B

       这时候B和C的引用计数分别为2和1.当A不再使用B,调用release释放对B的所有权,因为C还引用了B,所以B的引用计数为1,B不会释放。B不释放,C的引用计数就是1,C也不会被释放。从此,B和C永远留在内存中。这种情况,必须打断循环引用,通过其他规则来维护引用关系。比如,我们常见的delegate往往是assign方式的属性而不是retain方式的属性,赋值不会增加引用计数,就是为了防止delegation两段产生不必要的循环引用。如果一个UITableViewController对象A通过retain方式获取了了UITableView对象B的所有权,这个UITableView对象B的delegate又是对象A,如果这个delegate也是retain方式的,那么基本上就没有机会释放这两个对象了。我们自己在设计使用代理模式的时候,也需要注意这一点。

4. 用objective-c写冒泡排序

-(NSArray *)bubbleSort:(NSArray *) array{    for(int i=0; i<[array count]; i++)    {        for(int j=i+1; j<[array count]; j++)        {            int a = [[array objectAtIndex:i] intValue];            int b = [[array objectAtIndex:j] intValue];                if(a>b)            {                [array repalceObjectAtIndex:i withObject:[NSString stringWithFormat:@'%d',b]];                [array repalceObjectAtIndex:j withObject:[NSString stringWithFormat:@'%d',a]];            }        }    }    return array;}

5. 用预处理指令#define声明一个常数,用来表示1年中有多少秒(忽略闰年)

#define SECONDS_PER_YEAR (365*24*60*60)UL

另写一个标准宏MIN,这个宏输入两个参数并返回其中较小的一个:

#define MIN(A,B) ((A)<=(B)?(A):(B))

#define语法基本知识:不能以分号结尾,注意括号的使用。