精华内容
参与话题
问答
  • iOS面试题

    千次阅读 2013-07-10 20:48:27
    1.#import和#include的区别 @class? @class一般用于头文件中需要声明该类的某个实例变量的时候用到,在m文 件中还是需要使用#import 而#import比起#include的好处就是不会引起交叉编译   2. readwrite,readonly,...

    1.#import和#include的区别 @class?

    @class一般用于头文件中需要声明该类的某个实例变量的时候用到,在m文 件中还是需要使用#import

    而#import比起#include的好处就是不会引起交叉编译

     

    2. readwrite,readonly,assign,retain,copy,nonatomic 属性的作用

    @property是 一个属性访问声明,扩号内支持以下几个属性:
    1,getter=getName,setter=setName,设置setter与 getter的方法名
    2,readwrite,readonly,设置可供访问级别
    2,assign,setter方法直接赋值,不进行任何retain操作,为了解决原类型与环循引用问题
    3,retain,setter方法对参数进行release旧值再retain新值,所有 实现都是这个顺序(CC上有相关资料)
    4,copy,setter方法进行Copy操作,与retain处理流程一样,先旧值release,再 Copy出新的对象,retainCount为1。这是为了减少对上下文的依赖而引入的机制。
    5,nonatomic,非原子性访问,不加同步, 多线程并发访问会提高性能。注意,如果不加此属性,则默认是两个访问方法都为原子型事务访问。锁被加到所属对象实例级(我是这么理解的...)。

    3.在一个对象的方法里面:self.name= “object”;和
name =”object”
有什么不同吗?

    答:

    self.name ="object":会调用对象的setName()方法;

    name = "object":会直接把object赋值给当前对象的name属性。

     

    4.请简述self.name= nil的机制,以及与[namerelease]的区别?

    self.name =nil;   //使用nil参数调用setName:方法

    [name release]生成的访问器将自动释放以前的name对象

     

    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 。

     

    6.实例化一个UITableView对象,要求写出关键语句?

    答:UITableView *my = [[UITableView alloc]initWithFrame:<(CGRect)frame> style:<(UITableViewStyle)style>];

    my.delegate = self;

    my.dataSource = self;

    首先需要分配空间设置表格类型

    然后需要设置两个必须的委托对象。

     

    7.使用sql语句查询出省名以湖开头,邮编为436001所在的市区?(5分)(表名及字段名自定义)

    select*fromcitys where postcode=436001 and province=’湖%’;

    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年中有多少秒(忽略闰年问题)

    答:#defineSECONDS_PER_YEAR (60 * 60 * 24 * 365)UL  

    我在这想看到几件事情:  

     #define 语法的基本知识(例如:不能以分号结束,括号的使用,等等)  

    懂得预处理器将为你计算常数表达式的值,因此,直接写出你是如何计算一年中有多少秒而不是计算出实际的值,是更清晰而没有代价的。 

    意识到这个表达式将使一个16位机的整型数溢出-因此要用到长整型符号L,告诉编译器这个常数是的长整型数。  

    如果你在你的表达式中用到UL(表示无符号长整型),那么你有了一个好的起点。记住,第一印象很重要。  

     

    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.数组和指针的区别

    (1)数组可以申请在栈区和数据区;指针可以指向任意类型的内存块

    (2)sizeof作用于数组时,得到的是数组所占的内存大小;作用于指针时,得到的都是4个字节的大小

    (3)数组名表示数组首地址,值不可以改变,如不可以将++作用于数组名上;普通指针的值可以改变,如可将++作用于指针上

    (4)用字符串初始化字符数组是将字符串的内容拷贝到字符数组中;用字符串初始化字符指针是将字符串的首地址赋给指针,也就是指针指向了该数组

     

    12.static的作用

    (1)函数体内static 变量的作用范围为该函数体,不同于 auto 变量,该变量的内存只被分配一次, 

    因此其值在下次调用时仍维持上次的值; 

    (2)在模块内的static 全局变量可以被模块内所用函数访问,但不能被模块外其它函数访问; 

    (3)在模块内的static 函数只可被这一模块内的其它函数调用,这个函数的使用范围被限制在声明 

    它的模块内; 

    (4)在类中的static 成员变量属于整个类所拥有,对类的所有对象只有一份拷贝; 

    (5)在类中的static 成员函数属于整个类所拥有,这个函数不接收 this 指针,因而只能访问类的static 成员变量。

    13.简述内存分区情况

    (1)代码区:存放函数二进制代码

    (2)数据区:系统运行时申请内存并初始化,系统退出时由系统释放。存放全局变量、静态变量、常量

    (3)堆区:通过malloc等函数或new等操作符动态申请得到,需程序员手动申请和释放

    (4)栈区:函数模块内申请,函数结束时由系统自动释放。存放局部变量、函数参数

     

    14.#include<filename>和#include”filename”有什么区别

    答:#include<filename>直接在库文件目录中搜索所包含的文件;#include”filename”在当前目录下搜索所包含的文件,如果没有的话再到库文件目录搜索。

    15.const char *p;  charconst*p;  char*const p;  const char* const p;四个修饰指针有什么区别

    答:(1)定义了一个指向不可变的字符串的字符指针

       (2)和(1)一样

       (3)定义了一个指向字符串的指针,该指针值不可改变,即不可改变指向

    (4)定义了一个指向不可变的字符串的字符指针,且该指针也不可改变指向

    16.MVC的理解?

    答:MVC模式考虑三种对象:模型对象、视图对象和控制器对象。
模型对象负责应用程序的数据和定义操作数据的逻辑;
视图对象知道如何显示应用程序的模型数据;
控制器对象是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对应的权限是什么

    21.ARC机制

    ARC就是automatic reference counting ,简单说就是就是代码中自动加入了retain/release,原先需要手动添加的用来处理内存管理的引用计数的代码可以自动地由编译器完成了。

    使用ARC的好处

    使用ARC有什么好处呢?

    看到上面的例子,大家就知道了,以后写Objective-C的代码变得简单多了,因为我们不需要担心烦人的内存管理,担心内存泄露了

    代码的总量变少了,看上去清爽了不少,也节省了劳动力

    代码高速化,由于使用编译器管理引用计数,减少了低效代码的可能性

    不好的地方

    记住一堆新的ARC规则—关键字及特性等需要一定的学习周期

    一些旧的代码,第三方代码使用的时候比较麻烦;修改代码需要工数,要么修改编译开关

     

    22.自动释放池是什么,如何工作

    当您向一个对象发送一个autorelease 消息时,Cocoa就会将该对象的一个引用放入到最新的自动释放池。它仍然是个正当的对象,因此自动释放池定义的作用域内的其它对象可以向它发送消息。当程序执行到作用域结束的位置时,自动释放池就会被释放,池中的所有对象也就被释放。

    1. ojc-c 是 通过一种"referring counting"(引用计数)的方式来管理内存的, 对象在开始分配内存(alloc)的时候引用计数为一,以后每当碰到有copy,retain的时候引用计数都会加一, 每当碰到release和autorelease的时候引用计数就会减一,如果此对象的计数变为了0, 就会被系统销毁.
    2. NSAutoreleasePool 就是用来做引用计数的管理工作的,这个东西一般不用你管的.
    3. autorelease和release没什么区别,只是引用计数减一的时机不同而已,autorelease会在对象的使用真正结束的时候才做引用计数减一.

    23.ViewController 的 loadView, viewDidLoad,viewDidUnload 分别是在什么时候调用的?在自定义ViewController的时候这几个函数里面应该做什么工作?

    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 。

    24. 浅复制和深复制的区别?//浅拷贝和深拷贝


    答案:

    
浅层复制(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的优缺点 

    答案:

    objc优点: 

      1) Cateogies 

      2) Posing 

      3) 动态识别 

      4) 指标计算 

      5)弹性讯息传递 

      6) 不是一个过度复杂的 C 衍生语言 

      7) Objective-C 与 C++ 可混合编程 

    缺点: 

      1) 不支援命名空间 

      2)  不支持运算符重载 

      3) 不支持多重继承 

      4) 使用动态运行时类型,所有的方法都是函数调用,所以很多编译时优化方法都用不到。(如内联函数等),性能低劣。 

    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个图标?都具有什么功能。(10分)

    答:File’s Owner 是所有nib文件中的每个图标,它表示从磁盘加载nib文件的对象;

    First Responder就是用户当前正在与之交互的对象;

    View显示用户界面;完成用户交互;是UIView类或其子类。

    34.  简述视图控件器的生命周期(10分)。

    答:loadView尽管不直接调用该方法,如多手动创建自己的视图,那么应该覆盖这个方法并将它们赋值给试图控制器的view属性。

    viewDidLoad只有在视图控制器将其视图载入到内存之后才调用该方法,这是执行任何其他初始化操作的入口。

    viewDidUnload当试图控制器从内存释放自己的方法的时候调用,用于清楚那些可能已经在试图控制器中创建的对象。

    viewVillAppear当试图将要添加到窗口中并且还不可见的时候或者上层视图移出图层后本视图变成顶级视图时调用该方法,用于执行诸如改变视图方向等的操作。实现该方法时确保调用[super viewWillAppear:].

    viewDidAppear当视图添加到窗口中以后或者上层视图移出图层后本视图变成顶级视图时调用,用于放置那些需要在视图显示后执行的代码。确保调用[super viewDidAppear]

    35.  动画有基本类型有哪几种;表视图有哪几种基本样式(10分)?

    答:动画有两种基本类型:隐式动画和显式动画。

    36.  实现简单的表格显示需要设置UITableView的什么属性、实现什么协议(10分)?

    答:实现简单的表格显示需要设置UITableViewdataSourcedelegate属性,实现UITableViewDataSourceUITableViewDelegate协议。

    37.  Cocoa Touch提供了哪几种Core Animation过渡类型(10分)?

    答:Cocoa Touch提供了4Core Animation过渡类型,分别为:交叉淡化、推挤、显示和覆盖。

    38.  UIView与CLayer有什么区别(10分)?

    答:1. UIViewiOS系统中界面元素的基础,所有的界面元素都是继承自它。它本身完全是由CoreAnimation来实现的。它真正的绘图部分,是由一个CALayer类来管理。UIView本身更像是一个CALayer的管理器,访问它的跟绘图和跟坐标有关的属性。

    2. UIView有个重要属性layer,可以返回它的主CALayer实例。

    3. UIViewCALayer类似UIView的子View树形结构,也可以向它的layer上添加子layer,来完成某些特殊的表示。即CALayer层是可以嵌套的。

    4. UIViewlayer树形在系统内部,被维护着三份copy。分别是逻辑树,这里是代码可以操纵的;动画树,是一个中间层,系统就在这一层上更改属性,进行各种渲染操作;显示树,其内容就是当前正被显示在屏幕上得内容。

    5. 动画的运作:对UIViewsubLayer(非主Layer)属性进行更改,系统将自动进行动画生成,动画持续时间的缺省值似乎是0.5秒。

    6. 坐标系统:CALayer的坐标系统比UIView多了一个anchorPoint属性,使用CGPoint结构表示,值域是0~1,是个比例值。这个点是各种图形变换的坐标原点,同时会更改layerposition的位置,它的缺省值是{0.5,0.5},即在layer的中央。

    7.渲染:当更新层,改变不能立即显示在屏幕上。当所有的层都准备好时,可以调用setNeedsDisplay方法来重绘显示。

    8.变换:要在一个层中添加一个3D或仿射变换,可以分别设置层的transformaffineTransform属性。

    9.变形:Quartz Core的渲染能力,使二维图像可以被自由操纵,就好像是三维的。图像可以在一个三维坐标系中以任意角度被旋转,缩放和倾斜。CATransform3D的一套方法提供了一些魔术般的变换效果。

    39.链表翻转。

     

     

     

     

    40.  链表逆序(C语言)(10分)。

    链表逆序就是把一个链表按照原来的链接顺序逆序实现(也就是将头变成尾,尾变成头)。

    编程思路:其实最关键的是先通过原来的链接顺序找到下个节点,然后再把前个节点反序。

     

     

     

     

    41. Quatrz 2D的绘图功能的三个核心概念是什么并简述其作用(10分)。

    答:上下文:主要用于描述图形写入哪里;

    路径:是在图层上绘制的内容;

    状态:用于保存配置变换的值、填充和轮廓,alpha值等。

    42.  iPhone OS主要提供了几种播放音频的方法(10分)?

    答:SystemSound Services

    AVAudioPlayer

    Audio Queue Services

    OpenAL

    43.  使用AVAudioPlayer类调用哪个框架、使用步骤(10分)?

    答:AVFoundation.framework

    步骤:配置AVAudioPlayer对象;

    实现AVAudioPlayer类的委托方法;

    控制AVAudioPlayer类的对象;

    监控音量水平;

    回放进度和拖拽播放。

    44.  有哪几种手势通知方法、写清楚方法名(10分)?

    答:

    -(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对象,要求写出关键语句(10分)。

    答: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的方法(10分)?

    答:CFNetworkCFSocketBSD 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)向对象添加非正式协议。继承可以增加,修改方法,并且可以增加属性。

    51.通知和协议的不同之处?

    答案:协议有控制链(has-a)的关系,通知没有。首先我一开始也不太明白,什么叫控制链(专业术语了~)。但是简单分析下通知和代理的行为模式,我们大致可以有自己的理解简单来说,通知的话,它可以一对多,一条消息可以发送给多个消息接受者。代理按我们的理解,到不是直接说不能一对多,比如我们知道的明星经济代理人,很多时候一个经济人负责好几个明星的事务。只是对于不同明星间,代理的事物对象都是不一样的,一一对应,不可能说明天要处理A明星要一个发布会,代理人发出处理发布会的消息后,别称B发布会了。但是通知就不一样,他只关心发出通知,而不关心多少接收到感兴趣要处理。因此控制链(has-a从英语单词大致可以看出,单一拥有和可控制的对应关系。

     

    52.关于多态性


    答案:多态,子类指针可以赋值给父类。这个题目其实可以出到一切面向对象语言中,因此关于多态,继承和封装基本最好都有个自我意识的理解,也并非一定要把书上资料上写的能背出来。最重要的是转化成自我理解。

    53.对于单例的理解


    答案:基本能用熟悉的语言写出一个单例,以及可以运用到的场景或是你编程中碰到过运用的此种模式的框架类等。进一步点,考虑下如何在多线程访问单例时的安全性。

    54.  是否在一个视图控制器中嵌入两个tableview控制器?


    答案:一个视图控制只提供了一个View视图,理论上一个tableViewController也不能放吧,只能说可以嵌入一个tableview视图。当然,题目本身也有歧义,如果不是我们定性思维认为的UIViewController而是宏观的表示视图控制者,那我们倒是可以把其看成一个视图控制者,它可以控制多个视图控制器,比如TabbarController那样的感觉。

    55.
一个tableView是否可以关联两个不同的数据源?你会怎么处理?

    答案:首先我们从代码来看,数据源如何关联上的,其实是在数据源关联的代理方法里实现的。因此我们并不关心如何去关联他,他怎么关联上,方法只是让我返回根据自己的需要去设置如相关的数据源。因此,我觉得可以设置多个数据源啊,但是有个问题是,你这是想干嘛呢?想让列表如何显示,不同的数据源分区块显示?

    56.Object-c的类可以多重继承么?可以实现多个接口么?重写一个类的方式用继承好还是分类好?为什么?

    答案:Objective-c只支持单继承,如果要实现多继承的话,可以通过类别和协议的方式来实现,cocoa中所有的类都是NSObject 的子类,多继承在这里是用protocol 委托代理来实现的。

    57. id声明的对象有什么特性?

    答案:id是个很重要的类型,是个可以指向任何类型的指针或者可以理解为指向任何未知类型的指针。

    58.自动释放池跟GC(垃圾回收)有什么区别?iPhone上有GC么?[poolrelease] 和[pooldrain]有什么区别?

    iPhone上没有GCiPhone开发的时候没有垃圾回收机制。
    在垃圾回收环境中,release是一个空操作。因此,NSAutoreleasePool提供了drain方法,在引用计数环境中,该方法的作用等同于调用release,但在垃圾回收环境中,它会触发垃圾回收(如果自上次垃圾回收以来分配的内存大于当前的阈值)。因此,在通常情况下,您应该使用drain而不是release来销毁自动释放池。

    59.  线程与进程的区别和联系?

    答案: 进程和线程都是由操作系统所体会的程序运行的基本单元,系统利用该基本单元实现系统对应用的并发性。
    程和线程的主要差别在于它们是不同的操作系统资源管理方式。进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。

     

    60. ios平台怎么做数据的持久化?coredata和sqlite有无必然联系?coredata是一个关系型数据库吗?

    iOS中可以有四种持久化数据的方式:属性列表、对象归档、SQLite3Core Datacore data可以使你以图形界面的方式快速的定义app的数据模型,同时在你的代码中容易获取到它。coredata提供了基础结构去处理常用的功能,例如保存,恢复,撤销和重做,允许你在app中继续创建新的任务。在使用core data的时候,你不用安装额外的数据库系统,因为core data使用内置的sqlite数据库。core data将你app的模型层放入到一组定义在内存中的数据对象。coredata会追踪这些对象的改变,同时可以根据需要做相反的改变,例如用户执行撤销命令。当core data在对你app数据的改变进行保存的时候,core data会把这些数据归档,并永久性保存。
    mac os x
    sqlite库,它是一个轻量级功能强大的关系数据引擎,也很容易嵌入到应用程序。可以在多个平台使用,sqlite是一个轻量级的嵌入式sql数据库编程。与core data框架不同的是,sqlite是使用程序式的,sql的主要的API来直接操作数据表。
    Core Data
    不是一个关系型数据库,也不是关系型数据库管理系统(RDBMS)。虽然Core Dta支持SQLite作为一种存储类型,但它不能使用任意的SQLite数据库。Core Data在使用的过程种自己创建这个数据库。Core Data支持对一、对多的关系。

    61.obj-c有多重继承么?如果没有什么替代方法?

    cocoa 中所有的类都是NSObject的子类,多继承在这里是用protocol 委托代理来实现的。你不用去考虑繁琐的多继承,虚基类的概念。

    62.obj-c有私有方法么?私有变量呢?

    objective-c - 类里面的方法只有两种,静态方法和实例方法. 这似乎就不是完整的面向对象了,按照OO的原则就是一个对象只暴露有用的东西. 如果没有了私有方法的话, 对于一些小范围的代码重用就不那么顺手了. 在类里面声名一个私有方法

    @interface Controller : NSObject { NSString *something; }

    + (void)thisIsAStaticMethod;

    - (void)thisIsAnInstanceMethod;

    @end

    @interface Controller (private) -

    (void)thisIsAPrivateMethod;

    @end

     

    @private可以用来修饰私有变量

    在Objective‐C中,所有实例变量默认都是私有的,所有实例方法默认都是公有的

    63.假定输入的字符串中只包含字母和*号。编写函数fun,功能是,除了中间和尾部的*号外,

    将字符串中其他*号全部删除。编写时,不用c的其他函数。

    例:*****A*BC*DEF*G****    结果为:A*BC*DEF*G****

    void fun (char *a)

     {

    int j=0;

    char *p=a;

    while (*p=='*')p++;

    while (*p){

    a[j++]=*p;

    p++;

     }

    a[j]=0;

     }

    64.截取字符串”20|http://www.621life.com“ 中 ‘|’字符前面及后面的数据,分别输出它们(10分)。

    NSString *str = "20|http://www.621life.com";

    NSRange range = [strrangeOfString:@"|"];

    int location = range.location;

    NSString *str1 = [strsubstringToIndex:location];

    NSString *str2 = [str substringFromIndex:location+1];

    65.获取项目根路径,并在其下创建一个名称为userData的目录。(10分)。

    // 获取根路径

    NSArray *paths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);

    NSString *documentsDirectory = [paths objectAtIndex:];

    // 创建文件系统管理器

    NSFileManager *fileManager = [[NSFileManageralloc] init];

    // 判断userData目录是否存在

    if(![fileManagerfileExistsAtPath:[NSStringstringWithFormat:@"%@/userData",documentsDirectory]]) {

    // 不存在,创建一个userData目录

    [fileManagercreateDirectoryAtPath:[NSStringstringWithFormat:@"%@/userData",documentsDirectory]withIntermediateDirectories:falseattributes:nilerror:nil];

    }

    66.tableView的重用机制(10分)?

    UITableView通过重用单元格来达到节省内存的目的:通过为每个单元格指定一个重用标识符(reuseIdentifier),即指定了单元格的种类,以及当单元格滚出屏幕时,允许恢复单元格以便重用.对于不同种类的单元格使用不同的ID,对于简单的表格,一个标识符就够了.

    67.这段代码有什么问题吗

    @implementation Person  

    i.       (void)setAge:(int)newAge

    {  

    self.age = newAge;  

    }

    死循环

    68.用变量a给出下面的定义

    a)    一个整型

    b)    一个指向整型数的指针

    c)    一个指向指针的的指针,它指向的指针是指向一个整型数

    d)    一个有10个整型数的数组

    e)    一个有10个指针的数组,该指针是指向一个整型数的

    f)    一个指向有10个整型数数组的指针

    g)    一个指向函数的指针,该函数有一个整型参数并返回一个整型数

    h)    一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型数

     

    a)   int a;

    b)   int *a;

    c)   int **a;

    d)   int a[10]

    e)   int *a[10];

    f)   int (*a)[10];

    g)   int (*a)(int);

    i)   int (*a[10])(int);

     

    69.给定一个字符串,输出本字符串中只出现一次并且最靠前的那个字符的位置?

    比如"abaccddeeef" 则是b,输出2

     

    int find(char *_str)

    {

    char *p = _str;

    inti = 1;

    while (*p)

    {

    char *temp = _str;

    while (*temp)

    {

    if ((*p ==*temp)&&(p != temp))

    {

    break;

    }

    temp++;

    if (*temp == 0) {

    returni;

    }

    }

    i++;

    p++;

    }

    return-1;

    }

    #include<stdio.h>

    #include<stdlib.h>

    #include<string.h>

    intfind_char(constchar* str)

    {

    staticintpos[256];

    const unsigned char* p =(const unsigned char*)str;

    inti = 0;

    if( (!str) || (!(*str)) )return -1;

    memset(pos,-1,sizeof(pos));

    while(*p){

    if(pos[*p] == -1){

    pos[*p] = p-(const unsigned char*)str;

    }else{

    pos[*p] = -2;

    }

    p++;

    }

    for(i=0;i<sizeof(pos)/sizeof(pos[0]);i++){

    if(pos[i]>=0)returnpos[i];

    }

    return -1;

    }

    int main()

    {

    constchar* p ="abaccddeeef";

    intpos = find_char(p);

    printf("%d, it is'%c'\n",pos,pos!=-1?p[pos]:' ');

    p ="abcdefghijklmnopqrstuvwxyz "

    "abcdefghijklmnopqrstuwxyz";

    pos = find_char(p);

    printf("%d, it is'%c'\n",pos,pos!=-1?p[pos]:' ');

    return0;

    }

    70.objective-c中的数字对象都有哪些,简述它们与基本数据类型的区别是什么?

    在OC中NSNumber是数字对象,可以进行拆装箱操作!

    //将int转为NSNumber

    NSNumber *num = [NSNumber numberWithInt:123];

    //得到一个int

    inttestNum = [numintValue];

    71.用NSLog函数输出一个浮点类型,结果四舍五入,并保留一位小数

    NSLog(@”%0.1f”,4.4324);

    72.objective-c中的词典对象、可变词典对象是哪个,初始化一个含有两个键值对的可变词典对象,并动态的添加和删除一条记录,输出第一条记录.

    词典NSDictionary,可变词典NSMutableDictionary,

    //初始化一个可变词典,带有2个键值对

    NSMutableDictionary *dic =[NSMutableDictionarydictionaryWithObjectsAndKeys:@"value1",@"key1",@"value2",@"key2",nil];

    //添加

    [dicsetObject:@"value3"forKey:@"key3"];

    //删除

    [dicremoveObjectForKey:@"key3"];

    //获取(按key获取)

    [dicobjectForKey:@"key1"];

    73.获取项目根路径,并在其下创建一个名称为userData的目录。

    // 获取根路径

    NSArray *paths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);

    NSString*documentsDirectory = [paths objectAtIndex:];

    // 创建文件系统管理器

    NSFileManager *fileManager= [[NSFileManageralloc] init];

    // 判断userData目录是否存在

    if(![fileManagerfileExistsAtPath:[NSStringstringWithFormat:@"%@/userData",documentsDirectory]]) {

    // 不存在,创建一个userData目录

    [fileManagercreateDirectoryAtPath:[NSStringstringWithFormat:@"%@/userData",documentsDirectory]withIntermediateDirectories:falseattributes:nilerror:nil];

    }

    74.do-while与 while-do的区别?

    do-while 先执行循环体,然后判断条件,如果条件判断为ture,则继续执行循环体,如果判断为false,则不执行循环体

    while-do 是先判断条件是否正确,若正确则执行循环体,若不正确则不执行循环体。

    所以do-while至少循环一次,而while-do有可能一次也不循环。

    75.用C语言,求2到100内的所有素数和。

     

    #include<stdio.h>

    intisPrime(int n)             //求素数,这是最经典的算法代码。建议记住

    {

    inti;

    for(i=2;i*i<=n;i++)

    if(n%i==0)

    return 0;

    return 1;

    }

    int main()

    {

    inti,sum=0;

    for(i=2;i<100;i++)

    if( isPrime(i))

    sum+=i;

    printf("%5d",sum);

    return 0 ;

    }

    intisPrime(int n)

    {

       inti;

       for(i=2;i<=n/2;i++)

       {

          if(n%i==0)

             break;

       }

       if(i>n/2)

          return1;

       else

          return0;

    }

    76.单件实例是什么(10分)。

    Foundation 和 Application Kit框架中的一些只允许创象,即在当前程中的唯一例。例来,NSFileManager和NSWorkspace 在使用都是基于象的例化。当向类请例的候,它会向您传递单例的一个引用,如果该实不存在,首先例的分配 和初始化。 象充当控制中心的角色,负责指引或协调类的各种服。如果在概念上只有一个例(比如
    NSWorkspace
    ),就应该产生 一个例,而不是多个例;如果将来某一天可能有多个例,您可以使用例机制,而不是工厂方法或函数。 

    77.自动释放池是什么,如何工作。

    当您向一个对象发送一个autorelease消息时,Cocoa就会将该对象的一个引用放入到最新的自动释放池。它仍然是个正当的对象,因此自动释放池定义的作用域内的其它对象可以向它发送消息。当程序执行到作用域结束的位置时,自动释放池就会被释放,池中的所有对象也就被释放。

     


    展开全文
  • IOS 面试题

    千次阅读 2013-08-04 19:55:41
    面试能力要求:精通iphone的UI开发,能熟练操作复杂表视图,熟练使用图层技术, 可以自定义UI控件,使用类别扩展系统控件功能; 擅长通讯技术,熟悉各种通信协议,精通xml, json, 二进制或其他形式的自定义解析,...

    面试能力要求:精通iphone的UI开发,能熟练操作复杂表视图,熟练使用图层技术, 可以自定义UI控件,使用类别扩展系统控件功能;  

    擅长通讯技术,熟悉各种通信协议,精通xml, json, 二进制或其他形式的自定义解析,能架设服务器实现客户端与服务器的通讯以提交开发效率; 

    熟练掌握各种数据存储技术,如core data, sqlite,  对象序列化,文件读写操作,熟悉数据库的设计。  

    精通 object-c,java, c  等编程语言, 熟悉c++,对于 面向对象编程思想有深入理解,熟悉常见设计模式的应用,

    对于大型项目有一定的架构能力。

     

    1. ViewController的didReceiveMemoryWarning怎么被调用:

    [supper didReceiveMemoryWarning];

    2.什么时候用delegate,什么时候用Notification?

    delegate针对one-to-one关系,用于sender接受到reciever的某个功能反馈值。

    notification针对one-to-one/many/none,reciver,用于通知多个object某个事件。

     

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


    #define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL  
    我在这想看到几件事情:  
     #define 语法的基本知识(例如:不能以分号结束,括号的使用,等等)  
     懂得预处理器将为你计算常数表达式的值,因此,直接写出你是如何计算一年中有多少秒而不是计算出实际的值,是更清晰而没有代价的。
      
     意识到这个表达式将使一个16位机的整型数溢出-因此要用到长整型符号L,告诉编译器这个常数是的长整型数。  
     如果你在你的表达式中用到UL(表示无符号长整型),那么你有了一个好的起点。记住,第一印象很重要。

     

    写一个"标准"宏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会作三次++自增操作。

     

    4.写一个委托的 interface

    @protocol MyDelegate;

     
    @interface MyClass: NSObject

    {

        id <MyDelegate> delegate;

    }

    // 委托方法

    @protocol MyDelegate

    - (void)didJobs:(NSArray *)args;

    @end

     

    5. 写一个NSString类的实现

    + (id)initWithCString:(const char *)nullTerminatedCString encoding:(NSStringEncoding)encoding;

    + (id) stringWithCString: (const char*)nullTerminatedCString 
                encoding: (NSStringEncoding)encoding
    {
      NSString  *obj;

      obj = [self allocWithZone: NSDefaultMallocZone()];
      obj = [obj initWithCString: nullTerminatedCString encoding: encoding];
      return AUTORELEASE(obj);
    }

    6.obj-c有多重继承么?不是的话有什么替代方法?


    cocoa 中所有的类都是NSObject 的子类

    多继承在这里是用protocol 委托代理 来实现的 
    你不用去考虑繁琐的多继承 ,虚基类的概念.
    ood的多态特性  在 obj-c 中通过委托来实现.

     

    7.obj-c有私有方法么?私有变量呢

     objective-c - 类里面的方法只有两种, 静态方法和实例方法. 这似乎就不是完整的面向对象了,按照OO的原则就是一个对象只暴露有用的东西. 如果没有了私有方法的话, 对于一些小范围的代码重用就不那么顺手了. 在类里面声名一个私有方法

    @interface Controller : NSObject {

       NSString *something;

    }

    + (void)thisIsAStaticMethod;

    - (void)thisIsAnInstanceMethod;

    @end

    @interface Controller (private)

    -(void)thisIsAPrivateMethod;

    @end

     
    @private可以用来修饰私有变量

    在Objective‐C中,所有实例变量默认都是私有的,所有实例方法默认都是公有的。

    8.关键字const有什么含意?修饰类呢?static的作用,用于类呢?还有extern c的作用

    const 意味着"只读",下面的声明都是什么意思?  
    const int a;  
    int const a;  
    const int *a;  
    int * const a;  
    int const * a const; 

     
    前两个的作用是一样,a是一个常整型数。

    第三个意味着a是一个指向常整型数的指针(也就是,整型数是不可修改的,但指针可以)。

    第四个意思a是一个指向整型数的常指针(也就是说,指针指向的整型数是可以修改的,但指针是不可修改的)。

    最后一个意味着a是一个指向常整型数的常指针(也就是说,指针指向的整型数是不可修改的,同时指针也是不可修改的)。

    结论:

     关键字const的作用是为给读你代码的人传达非常有用的信息,实际上,声明一个参数为常量是为了告诉了用户这个参数的应用目的。

     如果你曾花很多时间清理其它人留下的垃圾,你就会很快学会感谢这点多余的信息。(当然,懂得用const的程序员很少会留下的垃圾让

     别人 来清理的。)   通过给优化器一些附加的信息,使用关键字const也许能产生更紧凑的代码。  


     合理地使用关键字const可以使编译器很自然地保护那些不希望被改变的参数,防止其被无意的代码修改。简而言之,这样可以减少bug

     的出  现。  
     

    (1)欲阻止一个变量被改变,可以使用 const 关键字。在定义该 const 变量时,通常需要对它进行初
    始化,因为以后就没有机会再去改变它了; 
    (2)对指针来说,可以指定指针本身为 const,也可以指定指针所指的数据为 const,或二者同时指
    定为 const; 
    (3)在一个函数声明中,const 可以修饰形参,表明它是一个输入参数,在函数内部不能改变其值; 
    (4)对于类的成员函数,若指定其为 const 类型,则表明其是一个常函数,不能修改类的成员变量; 
    (5)对于类的成员函数,有时候必须指定其返回值为 const 类型,以使得其返回值不为“左值”。

    关键字volatile有什么含意?并给出三个不同的例子。

    一个定义为 volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。

    精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。

    下面是volatile变量的几个例子: 

    并行设备的硬件寄存器(如:状态寄存器)  
     一个中断服务子程序中会访问到的非自动变量(Non-automatic variables)  
     多线程应用中被几个任务共享的变量


     一个参数既可以是const还可以是volatile吗?解释为什么。  
     一个指针可以是volatile 吗?解释为什么。 

    下面是答案:  
     是的。一个例子是只读的状态寄存器。它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它。  
     是的。尽管这并不很常见。一个例子是当一个中服务子程序修该一个指向一个buffer的指针时。 

    9. static 关键字的作用:

     
    (1)函数体内 static 变量的作用范围为该函数体,不同于 auto 变量,该变量的内存只被分配一次,
    因此其值在下次调用时仍维持上次的值; 
    (2)在模块内的 static 全局变量可以被模块内所用函数访问,但不能被模块外其它函数访问; 
    (3)在模块内的 static 函数只可被这一模块内的其它函数调用,这个函数的使用范围被限制在声明
    它的模块内; 
    (4)在类中的 static 成员变量属于整个类所拥有,对类的所有对象只有一份拷贝; 
    (5)在类中的 static 成员函数属于整个类所拥有,这个函数不接收 this 指针,因而只能访问类的static 成员变量。

     extern "C" 的作用

    (1)被 extern "C"限定的函数或变量是 extern 类型的;
         extern 是 C/C++语言中表明函数和全局变量作用范围(可见性)的关键字,该关键字告诉编译器,
         其声明的函数和变量可以在本模块或其它模块中使用。

    (2)被 extern "C"修饰的变量和函数是按照 C 语言方式编译和连接的; 
     extern "C"的惯用法 

    (1)在 C++中引用 C 语言中的函数和变量,在包含 C 语言头文件(假设为 cExample.h)时,需进
           行下列处理: 
      extern "C"  {  
       #include "cExample.h"  
      }  
    而在 C 语言的头文件中,对其外部函数只能指定为 extern 类型,C 语言中不支持 extern "C"声明,
    在.c 文件中包含了 extern "C"时会出现编译语法错误。

    (2)在 C 中引用 C++语言中的函数和变量时,C++的头文件需添加 extern "C",但是在 C 语言中不
    能直接引用声明了 extern "C"的该头文件,应该仅将 C 文件中将 C++中定义的 extern "C"函数声明为
    extern 类型。

     

    10.为什么标准头文件都有类似以下的结构?  
       #ifndef __INCvxWorksh  
       #define __INCvxWorksh  
       #ifdef __cplusplus  
       extern "C" {  
       #endif  
       /*...*/  
       #ifdef __cplusplus  
       }  
       #endif  
       #endif /* __INCvxWorksh */ 

    显然,头文件中的编译宏“#ifndef __INCvxWorksh、#define __INCvxWorksh、#endif” 的作用
    是防止该头文件被重复引用。

     

    10.#import跟#include的区别,@class呢?

     @class一般用于头文件中需要声明该类的某个实例变量的时候用到,在m文件中还是需要使用#import。
     而#import比起#include的好处就是不会引起交叉编译。

     

    11.MVC模式的理解

    MVC设计模式考虑三种对象:模型对象、视图对象、和控制器对象。

    模型对象代表特别的知识和专业技能,它们负责保有应用程序的数据和定义操作数据的逻辑。

    视图对象知道如何显示应用程序的模型数据,而且可能允许用户对其进行编辑。

    控制器对象是应用程序的视图对象和模型对象之间的协调者。

    12.线程与进程的区别和联系?

    进程和线程都是由操作系统所体会的程序运行的基本单元,系统利用该基本单元实现系统对应用的并发性。

    进程和线程的主要差别在于它们是不同的操作系统资源管理方式。

    进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。

    线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉。

    所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。

    但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。

     13.列举几种进程的同步机制,并比较其优缺点。

    答案:  原子操作 信号量机制    自旋锁    管程,会合,分布式系统


    1.进程之间通信的途径

    答案:共享存储系统消息传递系统管道:以文件系统为基础


    2.进程死锁的原因

    答案:资源竞争及进程推进顺序非法


    3.死锁的4个必要条件

    答案:互斥、请求保持、不可剥夺、环路


    4.死锁的处理

    答案:鸵鸟策略、预防策略、避免策略、检测与解除死锁

     

    14.堆和栈的区别


    管理方式:对于栈来讲,是由编译器自动管理,无需我们手工控制;对于堆来说,释放工作由程序员控制,容易产生memory leak。

    1.申请大小:
    栈:在Windows下,栈是向低地址扩展的数据结构,是一块连续的内存的区域。这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的,在WINDOWS下,栈的大小是2M(也有的说是1M,总之是一个编译时就确定的常数),如果申请的空间超过栈的剩余空间时,将提示 overflow。因此,能从栈获得的空间较小。


    堆:堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。

    2.碎片问题:对于堆来讲,频繁的new/delete势必会造成内存空间的不连续,从而造成大量的碎片,使程序效率降低。对于栈来讲,则不会存在这个问题,因为栈是先进后出的队列,他们是如此的一一对应,以至于永远都不可能有一个内存块从栈中间弹出

    3.分配方式:堆都是动态分配的,没有静态分配的堆。栈有2种分配方式:静态分配和动态分配。静态分配是编译器完成的,比如局部变量的分配。动态分配由 alloca函数进行分配,但是栈的动态分配和堆是不同的,他的动态分配是由编译器进行释放,无需我们手工实现。

    4.分配效率:栈是机器系统提供的数据结构,计算机会在底层对栈提供支持:分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行,这就决定了栈的效率比较高。堆则是C/C++函数库提供的,它的机制是很复杂的。

     
    15.什么是键-值,键路径是什么

    模型的性质是通过一个简单的键(通常是个字符串)来指定的。视图和控制器通过键来查找相应的属性值。

    在一个给定的实体中,同一个属性的所有值具有相同的数据类型。

    键-值编码技术用于进行这样的查找—它是一种间接访问对象属性的机制。

    键路径是一个由用点作分隔符的键组成的字符串,用于指定一个连接在一起的对象性质序列。第一个键的
    性质是由先前的性质决定的,接下来每个键的值也是相对于其前面的性质。键路径使您可以以独立于模型
    实现的方式指定相关对象的性质。通过键路径,您可以指定对象图中的一个任意深度的路径,使其指向相
    关对象的特定属性。

    16.c和obj-c如何混用

    1)obj-c的编译器处理后缀为m的文件时,可以识别obj-c和c的代码,处理mm文件可以识别obj-c,c,c++代码,

         但cpp文件必须只能用c/c++代码,而且cpp文件include的头文件中,也不能出现obj- c的代码,因为cpp只是cpp。
    2) 在mm文件中混用cpp直接使用即可,所以obj-c混cpp不是问题
    3)在cpp中混用obj- c其实就是使用obj-c编写的模块是我们想要的。
    如果模块以类实现,那么要按照cpp class的标准写类的定义,头文件中不能出现obj-c的东西,包括#import cocoa的。

    实现文件中,即类的实现代码中可以使用obj-c的东西,可以import,只是后缀是mm。
    如果模块以函数实现,那么头文件要按 c的格式声明函数,实现文件中,c++函数内部可以用obj-c,但后缀还是mm或m。

    总结:只要cpp文件和cpp include的文件中不包含obj-c的东西就可以用了,cpp混用obj-c的关键是使用接口,

    而不能直接使用实现代码,实际上cpp混用的是 obj-c编译后的o文件,这个东西其实是无差别的,所以可以用。obj-c的编译器支持cpp.


    17.cocoa touch框架


    iPhone OS 应用程序的基础 Cocoa Touch 框架重用了许多 Mac 系统的成熟模式,但是它更多地专注于触摸的接口和优化。

    UIKit 为您提供了在 iPhone OS 上实现图形,事件驱动程序的基本工具,其建立在和 Mac OS X 中一样的 Foundation 框架上,

    包括文件处理,网络,字符串操作等。

     
    Cocoa Touch 具有和 iPhone 用户接口一致的特殊设计。有了 UIKit,您可以使用 iPhone OS 上的独特的图形接口控件,按钮,

    以及全屏视图的功能,您还可以使用加速仪和多点触摸手势来控制您的应用。


    各色俱全的框架 除了 UIKit 外,Cocoa Touch 包含了创建世界一流 iPhone 应用程序需要的所有框架,从三维图形,到专业音效,

    甚至提供设备访问 API 以控制摄像头,或通过 GPS 获知当前位置。

    Cocoa Touch 既包含只需要几行代码就可以完成全部任务的强大的 Objective-C 框架,也在需要时提供基础的 C 语言 API 来直接访问系统。这些框架包括:

    Core Animation:通过 Core Animation,您就可以通过一个基于组合独立图层的简单的编程模型来创建丰富的用户体验。

    Core Audio:Core Audio 是播放,处理和录制音频的专业技术,能够轻松为您的应用程序添加强大的音频功能。

    Core Data:提供了一个面向对象的数据管理解决方案,它易于使用和理解,甚至可处理任何应用或大或小的数据模型。

    功能列表:框架分类
    下面是 Cocoa Touch 中一小部分可用的框架:

    音频和视频:Core Audio ,OpenAL ,Media Library ,AV Foundation 
    数据管理 :Core Data ,SQLite 
    图形和动画 :Core Animation ,OpenGL ES ,Quartz 2D 
    网络:Bonjour ,WebKit ,BSD Sockets 
    用户应用:Address Book ,Core Location ,Map Kit ,Store Kit

     

    18.自动释放池是什么,如何工作

     当您向一个对象发送一个autorelease消息时,Cocoa就会将该对象的一个引用放入到最新的自动释放池。

     它仍然是个正当的对象,因此自动释放池定义的作用域内的其它对象可以向它发送消息。

     当程序执行到作用域结束的位置时,自动释放池就会被释放,池中的所有对象也就被释放。

    1.  ojc-c 是通过一种"referring counting"(引用计数)的方式来管理内存的, 对象在开始分配内存(alloc)的时候引用计数为一,

         以后每当碰到有copy,retain的时候引用计数都会加一, 每当碰到release和autorelease的时候引用计数就会减一,如果此

         对象的计数变为了0, 就会被系统销毁.
    2. NSAutoreleasePool 就是用来做引用计数的管理工作的,这个东西一般不用你管的.
    3. autorelease和release没什么区别,只是引用计数减一的时机不同而已,autorelease会在对象的使用真正结束的时候才做引用计数减一.

    19.objc优点:
      1) Cateogies 
      2) Posing 
      3) 动态识别
      4) 指标计算 
      5)弹性讯息传递
      6) 不是一个过度复杂的 C 衍生语言
      7) Objective-C 与 C++ 可混合编程
       objc缺点: 
      1) 不支援命名空間 
      2)  不支持运算符重载
      3) 不支持多重继承
      4) 使用动态运行时类型,所有的方法都是函数调用,所以很多编译时优化方法都用不到。(如内联函数等),性能低劣。

     

    20.sprintf,strcpy,memcpy使用上有什么要注意的地方

     
    strcpy是一个字符串拷贝的函数,它的函数原型为strcpy(char *dst, const char *src);

    将src开始的一段字符串拷贝到dst开始的内存中去,结束的标志符号为 '\0',由于拷贝的长度不是由我们自己控制的,

    所以这个字符串拷贝很容易出错。具备字符串拷贝功能的函数有memcpy,这是一个内存拷贝函数,它的函数原型

    为memcpy(char *dst, const char* src, unsigned int len);

    将长度为len的一段内存,从src拷贝到dst中去,这个函数的长度可控。但是会有内存叠加的问题。

    sprintf是格式化函数。将一段数据通过特定的格式,格式化到一个字符串缓冲区中去。sprintf格式化的函数的长度不可控,

    有可能格式化后的字符串会超出缓冲区的大小,造成溢出。

    21. 用变量a给出下面的定义 

    a) 一个整型数(An integer)  
    b)一个指向整型数的指针( A pointer to an integer)  
    c)一个指向指针的的指针,它指向的指针是指向一个整型数( A pointer 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) 一个指向函数的指针,该函数有一个整型参数并返回一个整型数(A pointer to a function that takes an integer as an argument
     and returns an integer)  
    h) 一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型数( An array of ten pointers to functions t
    hat take an integer argument and return an integer )  
     
    答案是:  
    a) int a; // An integer  
    b) int *a; // A pointer to an integer  
    c) int **a; // A pointer to a pointer to an integer  
    d) int a[10]; // An array of 10 integers  
    e) int *a[10]; // An array of 10 pointers to integers  
    f) int (*a)[10]; // A pointer to an array of 10 integers  
    g) int (*a)(int); // A pointer to a function a that  takes an integer argument and returns an integer  
    h) int (*a[10])(int); // An array of 10 pointers to functions  that take an integer argument and return an integer

     

    22.readwrite,readonly,assign,retain,copy,nonatomic 属性的作用

    @property是一个属性访问声明,扩号内支持以下几个属性:
    1,getter=getterName,setter=setterName,设置setter与 getter的方法名
    2,readwrite,readonly,设置可供访问级别
    2,assign,setter方法直接赋值,不进行任何retain操作,为了解决原类型与环循引用问题
    3,retain,setter方法对参数进行release旧值再retain新值,所有实现都是这个顺序(CC上有相关资料)
    4,copy,setter方法进行Copy操作,与retain处理流程一样,先旧值release,再 Copy出新的对象,retainCount为1。

       这是为了减少对上下文的依赖而引入的机制。
    5,nonatomic,非原子性访问,不加同步,多线程并发访问会提高性能。注意,如果不加此属性,则默认是两个访问方法

       都为原子型事务访问。锁被加到所属对象实例级(我是这么理解的...)。

     

    23.http和scoket通信的区别。

    http是客户端用http协议进行请求,发送请求时候需要封装http请求头,并绑定请求的数据,服务器一般有web服务器配合(当然也非绝对)。 http请求方式为客户端主动发起请求,服务器才能给响应,一次请求完毕后则断开连接,以节省资源。服务器不能主动给客户端响应(除非采取http长连接技术)。iphone主要使用类是NSUrlConnection。


    scoket是客户端跟服务器直接使用socket“套接字”进行连接,并没有规定连接后断开,所以客户端和服务器可以保持连接通道,双方都可以主动发送数据。一般在游戏开发或股票开发这种要求即时性很强并且保持发送数据量比较大的场合使用。主要使用类是CFSocketRef。

    24.mvc设计模式是什么? 你还熟悉什么设计模式?

    设计模式:并不是一种新技术,而是一种编码经验,使用比如java中的接口,iphone中的协议,继承关系等基本手段,

    用比较成熟的逻辑去处理某一种类型的事情,总结为所谓设计模式。面向对象编程中,java已经归纳了23中设计模式。

    mvc设计模式 ,模型,视图,控制器,可以将整个应用程序在思想上分成三大块,对应是的数据的存储或处理,前台的显示,

    业务逻辑的控制。 Iphone本身的设计思想就是遵循mvc设计模式。其不属于23中设计模式范畴。

    代理模式:代理模式给某一个对象提供一个代理对象,并由代理对象控制对源对象的引用.比如一个工厂生产了产品,

    并不想直接卖给用户,而是搞了很多代理商,用户可以直接找代理商买东西,代理商从工厂进货.
    常见的如QQ的自动回复就属于代理拦截,代理模式在iphone中得到广泛应用.

    单例模式:说白了就是一个类不通过alloc方式创建对象,而是用一个静态方法返回这个类的对象。系统只需要拥有一个的全局对象,

    这样有利于我们协调系统整体的行为,比如想获得[UIApplication sharedApplication];任何地方调用都可以得到 UIApplication的对象,

    这个对象是全局唯一的。

    观察者模式: 当一个物体发生变化时,会通知所有观察这个物体的观察者让其做出反应。实现起来无非就是把所有观察者的对象给这个物体,

    当这个物体的发生改变,就会调用遍历所有观察者的对象调用观察者的方法从而达到通知观察者的目的。

    工厂模式:


    public class Factory{
      public static Sample creator(int which){
     
      if (which==1)
          return new SampleA();
      else if (which==2)
          return new SampleB();
          }
     }

    25.你了解svn,cvs等版本控制工具么?
    版本控制 svn,cvs 是两种版控制的器,需要配套相关的svn,cvs服务器。
    scm是xcode里配置版本控制的地方。版本控制的原理就是a和b同时开发一个项目,a写完当天的代码之后把代码提交给服务器,

    b要做的时候先从服务器得到最新版本,就可以接着做。 如果a和b都要提交给服务器,并且同时修改了同一个方法,就会产生代码冲突,

    如果a先提交,那么b提交时,服务器可以提示冲突的代码,b可以清晰的看到,并做出相应的修改或融合后再提交到服务器。

     

    26.什么是push(了解一下)。

    客户端程序留下后门端口,客户端总是监听针对这个后门的请求,于是 服务器可以主动像这个端口推送消息。

     

    27.静态链接库(了解一下)

    (此为.a文件,相当于java里的jar包,把一些类编译到一个包中,在不同的工程中如果导入此文件就可以使用里面的类,

      具体使用依然是#import “ xx.h”)。

     

    28.fmmpeg框架(了解一下)

    (音视频编解码框架,内部使用UDP协议针对流媒体开发,内部开辟了六个端口来接受流媒体数据,完成快速接受之目的).

     

    29.fmdb框架(了解一下)

    (数据库框架,对sqllite的数据操作进行了封装,使用着可把精力都放在sql语句上面)。

     

    30.320框架(了解一下)

    (ui框架,导入320工程作为框架包如同添加一个普通框架一样)。

      cover(open)   flower框架 (2d 仿射技术),内部核心类是CATransform3D.

     

    31.什么是沙箱模型?哪些操作是属于私有api范畴?


    某个iphone工程进行文件操作有此工程对应的指定的位置,不能逾越。

    iphone沙箱模型的有四个文件夹,分别是什么,永久数据存储一般放在什么位置,得到模拟器的路径的简单方式是什么.

    documents,tmp,app,Library。

    (NSHomeDirectory()),

    手动保存的文件在documents文件里

    Nsuserdefaults保存的文件在tmp文件夹里

     

    Documents 目录:您应该将所有de应用程序数据文件写入到这个目录下。这个目录用于存储用户数据或其它应该定期备份信息。
    AppName.app 目录:这是应用程序程序包目录,包含应用程序本身。由于应用程序必须经过签名,

    所以您在运行时不能对这个目录中内容进行修改,否则可能会使应用程序无法启动。
    Library 目录:这个目录下有两个子目录:Caches 和 Preferences
    Preferences 目录包含应用程序偏好设置文件。您不应该直接创建偏好设置文件,而是应该使用NSUserDefaults类来取得和设置应用程序偏好.
    Caches 目录用于存放应用程序专用支持文件,保存应用程序再次启动过程中需要信息。


    tmp 目录:这个目录用于存放临时文件,保存应用程序再次启动过程中不需要信息。
    获取这些目录路径方法:
    1,获取家目录路径函数:
    NSString *homeDir = NSHomeDirectory();
    2,获取Documents目录路径方法:
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *docDir = [paths objectAtIndex:0];
    3,获取Caches目录路径方法:
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
    NSString *cachesDir = [paths objectAtIndex:0];
    4,获取tmp目录路径方法:
    NSString *tmpDir = NSTemporaryDirectory();
    5,获取应用程序程序包中资源文件路径方法:
    例如获取程序包中一个图片资源(apple.png)路径方法:
    NSString *imagePath = [[NSBundle mainBundle] pathForResource:@”apple” ofType:@”png”];
    UIImage *appleImage = [[UIImage alloc] initWithContentsOfFile:imagePath];
    代码中mainBundle类方法用于返回一个代表应用程序包对象。


    文件IO写入
    1,将数据写到Documents目录:
    - (BOOL)writeApplicationData:(NSData *)data toFile:(NSString *)fileName {


       NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

       NSString *docDir = [paths objectAtIndex:0];

       if (!docDir) {

        NSLog(@”Documents directory not found!”); return NO;

       }

       NSString *filePath = [docDir stringByAppendingPathComponent:fileName];
       return [data writeToFile:filePath atomically:YES];

    }


    2,从Documents目录读取数据:
    - (NSData *)applicationDataFromFile:(NSString *)fileName {
       NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

       NSString *docDir = [paths objectAtIndex:0];

       NSString *filePath = [docDir stringByAppendingPathComponent:fileName];

       NSData *data = [[[NSData alloc] initWithContentsOfFile:filePath] autorelease];

       return data;

    }
    NSSearchPathForDirectoriesInDomains这个主要就是返回一个绝对路径用来存放我们需要储存文件。


    - (NSString *)dataFilePath {


       NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
       NSString *documentsDirectory = [paths objectAtIndex:0];
       return [documentsDirectory stringByAppendingPathComponent:@"shoppingCar.plist"];
    }


    NSFileManager* fm=[NSFileManager defaultManager];
    if(![fm fileExistsAtPath:[self dataFilePath]]){


    //下面是对该文件进行制定路径保存
    [fm createDirectoryAtPath:[self dataFilePath] withIntermediateDirectories:YES attributes:nil error:nil];


    //取得一个目录下得所有文件名
    NSArray *files = [fm subpathsAtPath: [self dataFilePath] ];


    //读取某个文件
    NSData *data = [fm contentsAtPath:[self dataFilePath]];


    //或者
    NSData *data = [NSData dataWithContentOfPath:[self dataFilePath]];
    }

    iphone常见私有api的应用(比如直接发送短信,访问沙箱之外的磁盘文件).

    32.你在开发项目中时,用到了哪些数据存储方式,iphone中常见的方式有哪些,各有什么区别?

    数据存储五种形式的应用范围和性能区别

    (core data,  sqllite,对象序列化,文件直接读写,NSUserDefault(保存数据到temp文件夹中))
    文件直接读写 >core data> 对象序列化> sqllite>NSUserDefault.


    33.线程的常见方法有哪些,你是如何处理多线程的,多线程同步问题你了解么?
    线程创建的几种方式,线程的加锁,休眠,唤醒,解锁,退出,

    多线程要考虑同步问题,解决同步问题的方式就是对某一资源加锁,当一个线程操作本资源时,其他线程不能操作 。

     
    系统自带线程池(NSOpertionQueue)的作用:

    凡是需要启动多个线程的地方都可以使用NSOpertionQueue,加入到NSOpertionQueue中的对象都需要继承NSOpertion。 NSOpertionQueue会在系统内部启动一个独立线程去执行这个被加入对象的main方法。

    常用的地方是用nsoprationqueue 下载图片,文件。如果是自己创建一个线程池,无非就是启动多个线程的时候,

    把这些线程对象放到一个大数组中,如果需要启动线程的时候,先从数组中找空闲线程来使用。

    自己管理线程池最大的难题是不好处理当启动多个线程后,用户在多个界面的跳转的时候,对线程方法的回调管理。

    而NSOpertionQueue可以很好的处理他。

     

    34.init和initwithobject区别(语法)?

       init创建的对象不带自动释放

     

    35.你连接服务器用的是什么方法,如果请求过程中,网络出了问题这么办?
    NSUrlConnection 连接后,有一系列委托方法来接受来自服务器的响应和数据,

    其中接受相应的方法回得到服务器要传回的数据有多大,接受数据的方法会反复调用来不断接受服务器数据,

    如果网络出了问题了,会调用一个方法让你来做相关处理。


    36.你使用过json解析方式么,他们的底层是如何处理的你了解么?


    json解析的用法,用框架的用法简单介绍:

    底层原理遍历字符串中的字符,最终根据格式规定的特殊字符,比如{}号,[]号, : 号 等进行区分,

     {}号是一个字典的开始,[]号是一个数组的开始, : 号是字典的键和值的分水岭,最终乃是将json数据转化为字典,

    字典中值可能是字典,数组,或字符串而已。

     

    37.xml解析的原理是什么,你还用过其他解析方式么?

    NSXMLParser, 其他解析方式有自定义二进制解析,就是按字节去解析,电话会谈就是如此,

    还可以是字符串之间用特殊符号连接的数据,将此数据用特殊符号可以分割成所用数据。

     

    38.协议是什么,有什么作用.?


    协议很像java中的接口,某个类实现协议后,就必须实现协议中规定的@require的方法,比如一个类A, 一个类B都实现某“协议”后,

    这个类A的对象和B的对象都可以赋值给这个协议的类型变量,比如  id<协议> 变量名 = A类或B类的对象,

    于是这个变量就完成了能够指向多个不同的类的对象并调用对象中的实现协议的方法。

    39.类别有什么作用?
    类别的使用 。 类别有三大作用,

    1. 可以使本来需要在.h中声明的方法放到.m文件中声明,达到了可以使方法不对外公开。

    2. 可以方便的扩展类,甚至系统类都可以轻易扩展,维护了代码原本的结构不受影响。

    3. 类别可以写到不同的.h或.m文件中,可以分散代码到跟类别的扩展功能想关联的地方,方便查看。

    40.分线程回调主线程方法是什么,有什么作用? 
    [self    performSelectorOnMainThread:@selector(buttonGo2) withObject:nil waitUntilDone:YES];
    [self performSelector:@selector(buttonGo2) onThread:[NSThread mainThread] withObject:nil waitUntilDone:YES];
    需要即时刷新ui控件的时候,经常使用。


    41.iphone阅读器,如果要读取一个文本文件,请问你是如何处理编码问题的?另外像pdf格式的文件,你如何读取。?


    iphone手机阅读器中对于PDF格式的阅读,可以直接用UIWebView控件显示,也可以从网上下到很多直接读取pdf格式的代码

    直接从pdf中得到数据。

    复杂表格动画
    - (void)insertRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation; -(void)deleteRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;
    - (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;

    42.你在开发大型项目的时候,如何进行内存泄露检测的?
      可以通过xcode的自带工具run---start with performance tool里有instruments下有个leaks工具,

      启动此工具后,运行项目,工具里可以显示内存泄露的情况,双击可找到源码位置,可以帮助进行内存泄露的处理。

     

    43.你做iphone开发时候,有哪些传值方式,view和view之间是如何传值的?

         压栈。

     

    44.让一个物体从界面中的一点运动到另外一点,有哪些方法?
    四种方式:1. beginAnimation

                  2. 线程

                  3. NSTimer

                  4. 图层动画(路径)


    45.你了解哪些加密方式?
       Base64, MD5, 循环右移位等.

     

    46.地图定位

    CLLocationManager位置管理器  使用Core Location框架来确定iphone的位置(GPS,蜂窝基站三角网,wps三种方式)    

    MKMapView提供了一套可植入的地图接口,可以让我们在应用中展示地图,并对其进行相关的操作。一般来说,我们可以指定一个展示区域,放一些标记在上面,还可以加盖一些层在上面。

    MKMapView依赖Google map里面相关服务(如Google Earth API等),所以地图的左下角会有Google字样。

     

    47.打开url

    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"tel://8004664411"]];mailto://   sms://

     

    48. http网络通信

    ASIHTTPRequest 是一个直接在CFNetwork上做的开源项目:提供直接提交(HTTP POST)文件的API,异步请求与队列,自动管理上传与下载队列管理机,ASIFormDataRequest用于适合上传文件,图片数据。

     

    49. 图片浏览

    UIImagePickerController可以从相册,相机,胶卷里获得图片。

     

    50. 对像序列化

    NSCoding    encodeWithCoder   initWithCoder

    NSKeyedUnarchiver   NSKeyedArchiver

     

    51. 各种picker

    UIDatePicker   UIPickerView

     

    52. 电影播放

         MPMoviePlayerController

         音乐播放

         MPMusicPlayerController

     

    53.线程 ?

          a. 线程的创建和使用规则?

             答:NSThread

                     三种方法

                    - (id)init; // designated initializer

                    - (id)initWithTarget:(id)target selector:(SEL)selector object:(id)argument;

                    + (void)detachNewThreadSelector:(SEL)aSelector toTarget:(id)aTarget withObject:(id)anArgument

                     - (void)start;

           b. 主分线程

              答:启动分线程,上面已提到!加到主线程方法performSelector!

              //加到主线程addData()是主线程的方法!只有加到主线程后,才能调用主线程的方法

             [target performSelector:@selector(addData:) onThread:[NSThread mainThread] withObject:item waitUntilDone:YES];

               //[target addData:item];//没有加到主线程后,调用主线程的方法!一定会崩!

     

          c.线程锁

             答:NSCondition

                     方法:

                     [thread lock];//加锁

                     sleep(n);//线程休眠

                     [thread singnal];//相当于通知,线程启动

                     [thread unlock];//解锁

                     [thread exit];//线程退出

     

    54.各种 排序算法?

         希尔排序、快速排序、冒泡排序、

     

    55.通信底层原理

        答:OSI七层模型

        7 应用层:    ftp,smtp,http,telnet,tftp(通过各种协议,最终还是包装成TCP数据包,发送到网络中!)

        6 表现层:

        5 会话层:

        4 传输层:    tcp udp

        3 网络层:    ip,ICMP,IGRP,EIGRP,OSPF,ARP

        2 数据链路层: STP,VT

        1 物理层:

     

    56. 为什么很多内置类如UITableViewController的delegate属性都是assign而不是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方式的,那基本上就没有机会释放这两个对象了。自己在设计使用delegate模式时,也要注意这点。

     

    57. 以下每行代码执行后,person对象的retain count分别是多少?

          Person *person = [[Person alloc] init]; count 1

          [person retain]; retain  count 2

          [person release];retain count 1

          [person release];retain count = 0

     

    58.在一个对象的方法里面:

          self.name = “object”;

          和

          name =”object”

          有什么不同吗?  

    答:self.name = "object"会调用对象的setName()方法,会使object引用计数加1,name = "object"会直接把object赋值给当前对象的name 属性,引用计数不增加。


    59.readwrite,readonly,assign,retain,copy,nonatomic属性的作用?

     

    @property是一个属性访问声明,扩号内支持以下几个属性:
1,getter=getterName,setter=setterName,设置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,非原子性访问,不加同步,多线程并发访问会提高性能。注意,如果不加此属性,则默认是两个访问方法都为原子型事务访问。锁被加到所属对象实例级(我是这么理解的…)。

    7,@synthesize xxx; 来实现实际代码



    60.1.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].

    展开全文
  • ios 面试题

    千次阅读 2013-03-20 09:19:06
    1、Object-C有多继承吗?没有的话用什么代替? cocoa 中所有的类都是NSObject 的子类 多继承在这里是用protocol 委托代理 来实现的 你不用去考虑繁琐的多继承 ,虚基类的概念. ...ood的多态特性 在 obj-c ...
    1、Object-C有多继承吗?没有的话用什么代替?
    
    cocoa 中所有的类都是NSObject 的子类
    多继承在这里是用protocol 委托代理 来实现的
    你不用去考虑繁琐的多继承 ,虚基类的概念.
    ood
    的多态特性  obj-c 中通过委托来实现.

    2、Object-C有私有方法吗?私有变量呢?
    objective-c – 类里面的方法只有两种, 静态方法和实例方法. 这似乎就不是完整的面向对象了,按照OO的原则就是一个对象只暴露有用的东西. 如果没有了私有方法的话, 对于一些小范围的代码重用就不那么顺手了. 在类里面声名一个私有方法
    @interface Controller : NSObject { NSString *something; }
    + (void)thisIsAStaticMethod;
    – (void)thisIsAnInstanceMethod;
    @end
    @interface Controller (private) -
    (void)thisIsAPrivateMethod;
    @end
    @private可以用来修饰私有变量
    在Objective‐C中,所有实例变量默认都是私有的,所有实例方法默认都是公有的


    3、关键字const什么含义?
    const意味着”只读”,下面的声明都是什么意思?
    const int a;
    int const a;
    const int *a;
    int * const a;
    int const * a const; 
    前两个的作用是一样,a是一个常整型数。第三个意味着a是一个指向常整型数的指针(也就是,整型数是不可修改的,但指针可以)。第四个意思a是一个指向整型数的常指针(也就是说,指针指向的整型数是可以修改的,但指针是不可修改的)。最后一个意味着a是一个指向常整型数的常指针(也就是说,指针指向的整型数是不可修改的,同时指针也是不可修改的)。
    结论:
    •; 关键字const的作用是为给读你代码的人传达非常有用的信息,实际上,声明一个参数为常量是为了告诉了用户这个参数的应用目的。如果
    你曾花很多时间清理其它人留下的垃圾,你就会很快学会感谢这点多余的信息。(当然,懂得用const的程序员很少会留下的垃圾让别人来清
    理的。)
    •; 通过给优化器一些附加的信息,使用关键字const也许能产生更紧凑的代码。
    •; 合理地使用关键字const可以使编译器很自然地保护那些不希望被改变的参数,防止其被无意的代码修改。简而言之,这样可以减少bug的出现。 
    欲阻止一个变量被改变,可以使用 const 关键字。在定义该 const 变量时,通常需要对它进行初
    始化,因为以后就没有机会再去改变它了;
    (2)对指针来说,可以指定指针本身为 const,也可以指定指针所指的数据为 const,或二者同时指
    定为 const;
    (3)在一个函数声明中,const 可以修饰形参,表明它是一个输入参数,在函数内部不能改变其值;
    (4)对于类的成员函数,若指定其为 const 类型,则表明其是一个常函数,不能修改类的成员变量;
    (5)对于类的成员函数,有时候必须指定其返回值为 const 类型,以使得其返回值不为“左值”。


    4、关键字volatile有什么含义?并给出三个不同例子?
    一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确地说就是,优化器在用到
    这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。下面是volatile变量的几个例子:
    • 并行设备的硬件寄存器(如:状态寄存器)
    • 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables)
    • 多线程应用中被几个任务共享的变量 
    • 一个参数既可以是const还可以是volatile吗?解释为什么。
    • 一个指针可以是volatile 吗?解释为什么。 
    下面是答案:
    • 是的。一个例子是只读的状态寄存器。它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它。
    • 是的。尽管这并不很常见。一个例子是当一个中服务子程序修该一个指向一个buffer的指针时。 
    static作用?
    函数体内 static 变量的作用范围为该函数体,不同于 auto 变量,该变量的内存只被分配一次,
    因此其值在下次调用时仍维持上次的值;
    (2)在模块内的 static 全局变量可以被模块内所用函数访问,但不能被模块外其它函数访问;
    (3)在模块内的 static 函数只可被这一模块内的其它函数调用,这个函数的使用范围被限制在声明
    它的模块内;
    (4)在类中的 static 成员变量属于整个类所拥有,对类的所有对象只有一份拷贝;
    (5)在类中的 static 成员函数属于整个类所拥有,这个函数不接收 this 指针,因而只能访问类的static 成员变量。


    6、#import和#include的区别,@class代表什么?
    @class一般用于头文件中需要声明该类的某个实例变量的时候用到,在m文件中还是需要使用#import
    而#import比起#include的好处就是不会引起重复包含

    7、线程和进程的区别?
    进程和线程都是由操作系统所体会的程序运行的基本单元,系统利用该基本单元实现系统对应用的并发性。
    进程和线程的主要差别在于它们是不同的操作系统资源管理方式。进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。


    8、堆和栈的区别?
    管理方式:对于栈来讲,是由编译器自动管理,无需我们手工控制;对于堆来说,释放工作由程序员控制,容易产生memory leak。
    申请大小:
    栈:在Windows下,栈是向低地址扩展的数据结构,是一块连续的内存的区域。这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的,在WINDOWS下,栈的大小是2M(也有的说是1M,总之是一个编译时就确定的常数),如果申请的空间超过栈的剩余空间时,将提示overflow。因此,能从栈获得的空间较小。
    堆:堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。
    碎片问题:对于堆来讲,频繁的new/delete势必会造成内存空间的不连续,从而造成大量的碎片,使程序效率降低。对于栈来讲,则不会存在这个问题,因为栈是先进后出的队列,他们是如此的一一对应,以至于永远都不可能有一个内存块从栈中间弹出
    分配方式:堆都是动态分配的,没有静态分配的堆。栈有2种分配方式:静态分配和动态分配。静态分配是编译器完成的,比如局部变量的分配。动态分配由alloca函数进行分配,但是栈的动态分配和堆是不同的,他的动态分配是由编译器进行释放,无需我们手工实现。
    分配效率:栈是机器系统提供的数据结构,计算机会在底层对栈提供支持:分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行,这就决定了栈的效率比较高。堆则是C/C++函数库提供的,它的机制是很复杂的。


    9、Object-C的内存管理?
    1.当你使用new,alloc和copy方法创建一个对象时,该对象的保留计数器值为1.当你不再使用该对象时,你要负责向该对象发送一条release或autorelease消息.这样,该对象将在使用寿命结束时被销毁.
    2.当你通过任何其他方法获得一个对象时,则假设该对象的保留计数器值为1,而且已经被设置为自动释放,你不需要执行任何操作来确保该对象被清理.如果你打算在一段时间内拥有该对象,则需要保留它并确保在操作完成时释放它.
    3.如果你保留了某个对象,你需要(最终)释放或自动释放该对象.必须保持retain方法和release方法的使用次数相等.



    10、为什么很多内置的类,如TableViewController的delegate的属性是assign不是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方式的,那基本上就没有机会释放这两个对象了。自己在设计使用delegate模式时,也要注意这点。


    11、定义属性时,什么情况使用copy、assign、retain?
    assign用于简单数据类型,如NSInteger,double,bool,
    retain和copy用于对象,
    copy用于当a指向一个对象,b也想指向同样的对象的时候,如果用assign,a如果释放,再调用b会crash,如果用copy 的方式,a和b各自有自己的内存,就可以解决这个问题。
    retain 会使计数器加一,也可以解决assign的问题。
    另外:atomic和nonatomic用来决定编译器生成的getter和setter是否为原子操作。在多线程环境下,原子操作是必要的,否则有可能引起错误的结果。
    加了atomic,setter函数会变成下面这样:
    if (property != newValue) {
    [property release];
    property = [newValue retain];
    }


    12、对象是什么时候被release的?
    引用计数为0时。
    autorelease实际上只是把对release的调用延迟了,对于每一个Autorelease,系统只是把该Object放入了当前的Autorelease pool中,当该pool被释放时,该pool中的所有Object会被调用Release。对于每一个Runloop,系统会隐式创建一个Autorelease pool,这样所有的release pool会构成一个象CallStack一样的一个栈式结构,在每一个Runloop结束时,当前栈顶的Autorelease pool会被销毁,这样这个pool里的每个Object(就是autorelease的对象)会被release。那什么是一个Runloop呢?一个UI事件,Timer call, delegate call, 都会是一个新的Runloop



    13、iOS有没有垃圾回收?
    Objective-C 2.0也是有垃圾回收机制的,但是只能在Mac OS X Leopard 10.5 以上的版本使用。



    14、tableView的重用机制?
    查看UITableView头文件,会找到NSMutableArray*  visiableCells,和NSMutableDictnery* reusableTableCells两个结构。visiableCells内保存当前显示的cells,reusableTableCells保存可重用的cells。
      TableView显示之初,reusableTableCells为空,那么tableView dequeueReusableCellWithIdentifier:CellIdentifier返回nil。开始的cell都是通过[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]来创建,而且cellForRowAtIndexPath只是调用最大显示cell数的次数。
      比如:有100条数据,iPhone一屏最多显示10个cell。程序最开始显示TableView的情况是:
      1. 用[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]创建10次cell,并给cell指定同样的重用标识(当然,可以为不同显示类型的cell指定不同的标识)。并且10个cell全部都加入到visiableCells数组,reusableTableCells为空。
      2. 向下拖动tableView,当cell1完全移出屏幕,并且cell11(它也是alloc出来的,原因同上)完全显示出来的时候。cell11加入到visiableCells,cell1移出visiableCells,cell1加入到reusableTableCells。
    3. 接着向下拖动tableView,因为reusableTableCells中已经有值,所以,当需要显示新的cell,cellForRowAtIndexPath再次被调用的时候,tableView dequeueReusableCellWithIdentifier:CellIdentifier,返回cell1。cell1加入到visiableCells,cell1移出reusableTableCells;cell2移出visiableCells,cell2加入到reusableTableCells。之后再需要显示的Cell就可以正常重用了。



    15、ViewController 的loadView、viewDidLoad、viewDidUnload分别是什么时候调用的,在自定义ViewCointroller时在这几个函数中应该做什么工作?
    由init、loadView、viewDidLoad、viewDidUnload、dealloc的关系说起
    init方法
    在init方法中实例化必要的对象(遵从LazyLoad思想)
    init方法中初始化ViewController本身
    loadView方法
    当view需要被展示而它却是nil时,viewController会调用该方法。不要直接调用该方法。
    如果手工维护views,必须重载重写该方法
    如果使用IB维护views,必须不能重载重写该方法
    loadView和IB构建view
    你在控制器中实现了loadView方法,那么你可能会在应用运行的某个时候被内存管理控制调用。 如果设备内存不足的时候, view 控制器会收到didReceiveMemoryWarning的消息。 默认的实现是检查当前控制器的view是否在使用。如果它的view不在当前正在使用的view hierarchy里面,且你的控制器实现了loadView方法,那么这个view将被release, loadView方法将被再次调用来创建一个新的view。
    viewDidLoad方法
    viewDidLoad 此方法只有当view从nib文件初始化的时候才被调用。
    重载重写该方法以进一步定制view
    在iPhone OS 3.0及之后的版本中,还应该重载重写viewDidUnload来释放对view的任何索引
    viewDidLoad后调用数据Model
    viewDidUnload方法
    当系统内存吃紧的时候会调用该方法(注:viewController没有被dealloc)
    内存吃紧时,在iPhone OS 3.0之前didReceiveMemoryWarning是释放无用内存的唯一方式,但是OS 3.0及以后viewDidUnload方法是更好的方式
    在该方法中将所有IBOutlet(无论是property还是实例变量)置为nil(系统release view时已经将其release掉了)
    在该方法中释放其他与view有关的对象、其他在运行时创建(但非系统必须)的对象、在viewDidLoad中被创建的对象、缓存数据等 release对象后,将对象置为nil(IBOutlet只需要将其置为nil,系统release view时已经将其release掉了)
    一般认为viewDidUnload是viewDidLoad的镜像,因为当view被重新请求时,viewDidLoad还会重新被执行
    viewDidUnload中被release的对象必须是很容易被重新创建的对象(比如在viewDidLoad或其他方法中创建的对象),不要release用户数据或其他很难被重新创建的对象
    dealloc方法
    viewDidUnload和dealloc方法没有关联,dealloc还是继续做它该做的事情



    16、ViewController的didReceiveMemoryWarning是在什么时候调用的?默认的操作是什么?
    当程序接到内存警告时View Controller将会收到这个消息:didReceiveMemoryWarning
    从iOS3.0开始,不需要重载这个函数,把释放内存的代码放到viewDidUnload中去。
    这个函数的默认实现是:检查controller是否可以安全地释放它的view(这里加粗的view指的是controller的view属性),比如view本身没有superview并且可以被很容易地重建(从nib或者loadView函数)。
    如果view可以被释放,那么这个函数释放view并调用viewDidUnload。
    你可以重载这个函数来释放controller中使用的其他内存。但要记得调用这个函数的super实现来允许父类(一般是UIVIewController)释放view。
    如果你的ViewController保存着view的子view的引用,那么,在早期的iOS版本中,你应该在这个函数中来释放这些引用。而在iOS3.0或更高版本中,你应该在viewDidUnload中释放这些引用。



    17、列举Cocoa中常见的集中多线程的实现,并谈谈多线程安全的几种解决办法,一般什么地方会用到多线程?
    NSThread,GCD等。尽量用上层分装好的方法去实现多线程而不是手动调用NSThread。


    18、怎么理解MVC,在Cocoa中MVC是怎么实现的?
    Model: 代表你的应用程序是什么(不是怎么展现)
    Controller: 控制你的Model怎么展现给用户(UI逻辑)
    View: Controller的奴隶。。。

    Model,Controller,View相互通讯的规则:
    1. Controller可以直接和Model通信
    2. Controller也可以直接和View通信
    3. Model和View永远不能直接通信
    4. iOS中View和Controller的通信是透明和固定的,主要通过outlet和action实现
    5. View使用Delegate接口和Controller同步信息
    6. View不直接和数据通信,使用dataSource接口从Controller处获取数据
    7. View的delegate和dataSource一般就是Controller
    8. Controller负责为View翻译和格式化Model的数据
    9. Model使用Notification & KVO的方式分发数据更新信息,Controller可以有选择的监听自己感兴趣的信息。
    10. View也可以监听广播信息,但一般不是Model发出的信息
    11. 一个完整的App就是很多MVC的集合



    19、delegate和notification区别,分别在什么情况下使用?

    Delegate:
    消息的发送者(sender)告知接收者(receiver)某个事件将要发生,delegate同意然然后发送者响应事件,delegate机制使得接收者可以改变发送者的行为。通常发送者和接收者的关系是直接的一对多的关系。

    Notification:
    消息的发送者告知接收者事件已经发生或者将要发送,仅此而已,接收者并不能反过来影响发送者的行为。通常发送者和接收者的关系是间接的多对多关系。

     

    1. 效率肯定是delegate比nsnotification高。

    2. delegate方法比notification更加直接,最典型的特征是,delegate方法往往需要关注返回值,也就是delegate方法的结果。比如-windowShouldClose:,需要关心返回的是yes还是no。所以delegate方法往往包含should这个很传神的词。也就是好比你做我的delegate,我会问你我想关闭窗口你愿意吗?你需要给我一个答案,我根据你的答案来决定如何做下一步。相反的,notification最大的特色就是不关心接受者的态度,我只管把通告放出来,你接受不接受就是你的事情,同时我也不关心结果。所以notification往往用did这个词汇,比如NSWindowDidResizeNotification,那么nswindow对象放出这个notification后就什么都不管了也不会等待接受者的反应。

     

    1)两个模块之间联系不是很紧密,就用notification传值,例如多线程之间传值用notificaiton。

    2)delegate只是一种较为简单的回调,且主要用在一个模块中,例如底层功能完成了,需要把一些值传到上层去,就事先把上层的函数通过delegate传到底层,然后在底层call这个delegate,它们都在一个模块中,完成一个功能,例如说 NavgationController 从 B 界面到A 点返回按钮 (调用popViewController方法) 可以用delegate比较好。



    20、self.跟self什么区别?


    21、id、nil代表什么?

    id和void *并非完全一样。在上面的代码中,id是指向struct objc_object的一个指针,这个意思基本上是说,id是一个指向任何一个继承了Object(或者NSObject)类的对象。需要注意的是id是一个指针,所以你在使用id的时候不需要加星号。比如id foo=nil定义了一个nil指针,这个指针指向NSObject的一个任意子类。而id *foo=nil则定义了一个指针,这个指针指向另一个指针,被指向的这个指针指向NSObject的一个子类。

    nil和C语言的NULL相同,在objc/objc.h中定义。nil表示一个Objctive-C对象,这个对象的指针指向空(没有东西就是空)。

    首字母大写的Nil和nil有一点不一样,Nil定义一个指向空的类(是Class,而不是对象)。

    SEL是“selector”的一个类型,表示一个方法的名字

    Method(我们常说的方法)表示一种类型,这种类型与selector和实现(implementation)相关

     

    IMP定义为 id (*IMP) (idSEL, …)。这样说来, IMP是一个指向函数的指针,这个被指向的函数包括id(“self”指针),调用的SEL(方法名),再加上一些其他参数.说白了IMP就是实现方法。



    22、内存管理 Autorelease、retain、copy、assign的set方法和含义?

     

    1,你初始化(alloc/init)的对象,你需要释放(release)它。例如:

      NSMutableArray aArray = [[NSArray alloc] init];

      后,需要

      [aArray release];

      2,你retain或copy的,你需要释放它。例如:

      [aArray retain]

      后,需要

      [aArray release];

      3,被传递(assign)的对象,你需要斟酌的retain和release。例如:

      obj2 = [[obj1 someMethod] autorelease];

      对象2接收对象1的一个自动释放的值,或传递一个基本数据类型(NSInteger,NSString)时:你或希望将对象2进行retain,以防止它在被使用之前就被自动释放掉。但是在retain后,一定要在适当的时候进行释放。

     

    关于索引计数(Reference Counting)的问题

      retain值 = 索引计数(Reference Counting)

      NSArray对象会retain(retain值加一)任何数组中的对象。当NSArray被卸载(dealloc)的时候,所有数组中的对象会被执行一次释放(retain值减一)。不仅仅是NSArray,任何收集类(Collection Classes)都执行类似操作。例如NSDictionary,甚至UINavigationController。

      Alloc/init建立的对象,索引计数为1。无需将其再次retain。

      [NSArray array]和[NSDate date]等“方法”建立一个索引计数为1的对象,但是也是一个自动释放对象。所以是本地临时对象,那么无所谓了。如果是打算在全Class中使用的变量(iVar),则必须retain它。

      缺省的类方法返回值都被执行了“自动释放”方法。(*如上中的NSArray)

      在类中的卸载方法“dealloc”中,release所有未被平衡的NS对象。(*所有未被autorelease,而retain值为1的)



    23、类别的作用?

     

    有时我们需要在一个已经定义好的类中增加一些方法,而不想去重写该类。比如,当工程已经很大,代码量比较多,或者类中已经包住很多方法,已经有其他代码调用了该类创建对象并使用该类的方法时,可以使用类别对该类扩充新的方法。

      注意:类别只能扩充方法,而不能扩充成员变量。



    24、委托(举例)

     

    委托代理(degegate),顾名思义,把某个对象要做的事情委托给别的对象去做。那么别的对象就是这个对象的代理,代替它来打理要做的事。反映到程序中,首先要明确一个对象的委托方是哪个对象,委托所做的内容是什么。

    委托机制是一种设计模式,在很多语言中都用到的,这只是个通用的思想,网上会有很多关于这方面的介绍。

    那么在苹果开发过程中,用到委托的程序实现思想如下,我主要拿如何在视图之间传输信息做个例子。

    譬如:在两个页面(UIIview视图对象)实现传值,用委托(delegate)可以很好做到!

    方法:

    类A

    @interface A:UIView

            id transparendValueDelegate;

           @property(nomatic, retain) id transparendValueDelegate;

    @end


    @implemtion A

    @synthesize transparendValueDelegate

    -(void)Function

          NSString* value = @"hello";

          //让代理对象执行transparendValue动作

          [transparendValueDelegate transparendValue: value];

    }

    @end


    类B

    @interface B:UIView

          NSString* value;

    @end

    @implemtion B

    -(void)transparendValue:(NSString*)fromValue

    {

          value = fromValue;

          NSLog(@"the value is %@ ",value); 

    }

    @end


    //下面的设置A代理委托对象为B

    //在定义A和B类对象处:

    A* a = [[A alloc] init];

    B* b = [[B alloc] init];

    a. transparendValueDelegate = b;//设置对象a代理为对象b

    这样在视图A和B之间可以通过委托来传值!


    25、retainCount?


    26..属性readwrite,readonly,assign,retain,copy,nonatomic 各是什么作用,在那种情况下用

     

    assign:指定setter方法用简单的赋值,这是默认操作。你可以对标量类型(如int)使用这个属性。你可以想象一个float,它不是一个对象,所以它不能retain、copy。

    retain:指定retain应该在后面的对象上调用,前一个值发送一条release消息。你可以想象一个NSString实例,它是一个对象,而且你可能想要retain它。

    copy:指定应该使用对象的副本(深度复制),前一个值发送一条release消息。基本上像retain,但是没有增加引用计数,是分配一块新的内存来放置它。

    readonly:将只生成getter方法而不生成setter方法(getter方法没有get前缀)。

    readwrite:默认属性,将生成不带额外参数的getter和setter方法(setter方法只有一个参数)。

    atomic:对于对象的默认属性,就是setter/getter生成的方法是一个原子操作。如果有多个线程同时调用setter的话,不会出现某一个线程执行setter全部语句之前,另一个线程开始执行setter的情况,相关于方法头尾加了锁一样。

    nonatomic:不保证setter/getter的原子性,多线程情况下数据可能会有问题。


    27.类变量的@protected ,@private,@public,@package声明各有什么含义

     Objective-C 对存取权限的设定。也是变量的作用域。 
     
     protected 该类和所有的子类中的方法可以直接访问这样的变量,这是默认的。 
     
     private — 该类中的方法可以访问这样的变量,子类不可以。 public — 除了自己和子类中的方法外,也可以被其他类或者其他模块中的方法所访问。开放性最大。 package — 对于64位图像,这样的成员变量可以在实现这个类的图像中随意访问。 



    28.浅拷贝和深拷贝区别是什么

     简单的来说就是,在有指针的情况下,浅拷贝只是增加了一个指针指向已经存在的内存,而深拷贝就是增加一个指针并且申请一个新的内存,使这个增加的指针指向这个新的内存,采用深拷贝的情况下,释放内存的时候就不会出现在浅拷贝时重复释放同一内存的错误 
     
     
     
     
     29.Cocoa中与虚基类的概念么?怎么简洁的实现 
     
     
     
     
     30.NSString 和 NSMutableString 有什么区别 
     
    NSString相当于一个const char* 不可以改变。
    而 NSMutableString相当于 char* 可以改变内部的内容。


    31.自动释放池跟GC有什么区别?iPhone上有GC么?[pool release] 和[pool drain]有什么区别
    ”Autorelease Pools”(自动释放池)在应用中的使用技巧。 1,Autorelease Pools概要 一个”Autorelease Pool”实例中“包含”其它各种调用了”autorelease”方法的对象。当它释放时,其中所有被管理对象都会收到”relrease”的消信。注意,同一个对象可以被多次调用”autorelease”方法,并可以放到同一个”Autorelease Pool”中。引入这个自动释放池机制,对象的”autorelease”方法代替”relrease”方法可以延长它的生命周期,直接到当前”Autorelrease Pool”释放。如果想让此对象的生命周期超过”Autorelease Pool”,还可以再次”retain”,呵呵,有意思吧?且让我慢慢道来。 Cocoa总是认为当前至少有一个”Autorelease Pool”对象是可用的。若此对象并不存在,你调用的”autorelease”的所有对象都不会被自动释放掉,可想而知,造成内存泄露。Cocoa把这个错误信息写入日志??仅仅是为了以后分析。 你可以用”alloc”与”init”方法创建一个”NSAutoreleasePool”对象,并且可以调用”release”或”drain”(”release”与”drain”的区别是”drain”在有GC的环境中会引起GC回收操作,”release”反之。但在非GC环境中,两者相同。官方的说法是为了程序的兼容性,应该考虑用”drain”代替”release”,)方法来回收它(调用它的”autorelease”或”retain”方法会引起异常)。在一个完整的上下文最后”Autorelease Pool”对象应该被”release”掉(在方法内或一段循环体内创建的”Autorelease Pool”对象)。 “Autorelease Pools”的所有实例在栈中管理(我们暂时叫他“自动释放池栈”),并且它们是可以被嵌套的(父生子,子生孙。。。子子孙孙 ^_^)。例如,当我们创建一个”Autorelease Pool”对象后,它就被自动放到“自动释放池栈”的栈顶。当本池对象回收时,它就随之从这个栈中POP掉。那么也就是说,当任何一个对象调用”autorelease”方法后,它会被放入当前线程中当前栈顶的自动释放池中。 接下来我们聊聊”Autorelease Pools”的嵌套问题。在你的应用中,你可以任意多的创建”Autorelease Pool”对象,而这些对象被当前线程的“自动释放池栈”所管理。那么除了一个接一个的顺序创建并销毁它的情况外,还有一种使用方式,就是嵌套式的创建与使用。例如:在你的主函数创建了一个”autorelease pool”,然后又调用了创建了”autorelease pool”实例的其它方法;或是在外循环中创建了”Autorelease Pool”的实例,而内循环中也做了相同的事情。有意思吧,呵呵,嵌套的机制使父Pool实例释放后,它的所有子Pool也将释放。但这里还存在一些副作用,后续文章会详细讨论。 “Application kit”在一个事件循环里会自动创建一个”autorelease pool”。像鼠标键的按下与释放,所以你编写的代码通常不需要考虑太多这方面的事情。当然,有以下三种情况你会创建与销毁自己的Pool实例:    1,应用不是基于”Application Kit”,像”Command-line tool”,因为它并没有内置的”autorelease pools”的支持。    2,创建线程,你必需在线程开始时创建一个”Autorelease Pool”实例。反之,会造成内存池露(会在以后的文章详细说明线程与池的技巧)。    3,一个循环内创建了太多的临时对象,你应该为他们创建一个”Autorelease Pool”对象,并在下次循还前销毁它们。 2,自动释放池中的”Non-AppKit”应用 在”Non-AppKit”应用中使用自动释放池的机制其实是相当简单的事情。你仅仅需要在main()起始处创建”Autorelease Pool”对象,并在结尾处释放掉它。就像在Xcode的Foundation Tool的创建模版里写的一样。这个确保你在应用生命周期内至少有一个”Autorelease Pool”是可用的。但是,这也使所有在此期间的所有”autorelease”的对象都必需在应用结束后才被释放。这也许会引起在应用的使用中不断的增长,所以,你仍然考虑在不同的作用域创建新的”Autorelease Pool”。 大多应用中都存在各种级别的循环机制。在这些应用中,你可以在每个循环内的开头创建一个”Autorelease Pool”对象,并在结尾处释放掉它。 例如: void main() {     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];     NSArray *args = [[NSProcessInfo processInfo] arguments];     unsigned count, limit = [args count];     for (count = 0; count < limit; count++)     {         NSAutoreleasePool *loopPool = [[NSAutoreleasePool alloc] init];         NSString *fileContents;         NSString *fileName;         fileName = [args objectAtIndex:count];         fileContents = [[[NSString alloc] initWithContentsOfFile:fileName] autorelease];         // this is equivalent to using stringWithContentsOfFile:                 [loopPool release];     }         [pool drain];     exit (EXIT_SUCCESS); } 在命令行中处理所有以参数传来的文件。一次循环处理一个文件。在循环的开头创建一个”NSAutoreleasePool”对象,并在循环结束时释放掉。因此,任何在其中创建并调用“autorelease”的对象都将添加到这个Pool实例中,当本池被释放后,这些对象也将被回收。注意,任何在作用域内创建的”autoreleased”对象(像”fileName”),虽然并没有显示的调用”autorelease”方法,但都将被当前池所管理并释放。


    32.C和obj-c 如何混用
    1)obj-c的编译器处理后缀为m的文件时,可以识别obj-c和c的代码,处理mm文件可以识别obj-c,c,c++代码,但cpp文件必须只能用c/c++代码,而且cpp文件include的头文件中,也不能出现obj-c的代码,因为cpp只是cpp 2) 在mm文件中混用cpp直接使用即可,所以obj-c混cpp不是问题 3)在cpp中混用obj-c其实就是使用obj-c编写的模块是我们想要的。 如果模块以类实现,那么要按照cpp class的标准写类的定义,头文件中不能出现obj-c的东西,包括#import cocoa的。实现文件中,即类的实现代码中可以使用obj-c的东西,可以import,只是后缀是mm。 如果模块以函数实现,那么头文件要按c的格式声明函数,实现文件中,c++函数内部可以用obj-c,但后缀还是mm或m。 总结:只要cpp文件和cpp include的文件中不包含obj-c的东西就可以用了,cpp混用obj-c的关键是使用接口,而不能直接使用实现代码,实际上cpp混用的是obj-c编译后的o文件,这个东西其实是无差别的,所以可以用。obj-c的编译器支持cpp
    33.响应者链是什么 响应者链是Application Kit事件处理架构的中心机制。它由一系列链接在一起的响应者对象组成,事件或者动作消息可以沿着这些对象进行传递。如图6-20显示的那样,如果一个响应者对象不能处理某个事件或动作-也就是说,它不响应那个消息,或者不认识那个事件,则将该消息重新发送给链中的下一个响应者。消息沿着响应者链向上、向更高级别的对象传递,直到最终被处理(如果最终还是没有被处理,就会被抛弃)。
      当Application Kit在应用程序中构造对象时,会为每个窗口建立响应者链。响应者链中的基本对象是NSWindow对象及其视图层次。在视图层次中级别较低的视图将比级别更高的视图优先获得处理事件或动作消息的机会。NSWindow中保有一个第一响应者的引用,它通常是当前窗口中处于选择状态的视图,窗口通常把响应消息的机会首先给它。对于事件消息,响应者链通常以发生事件的窗口对应的NSWindow对象作为结束,虽然其它对象也可以作为下一个响应者被加入到NSWindow对象的后面。
    34..UIscrollVew用到了什么设计模式?还能再foundation库中找到类似的吗?
    组合模式composition,所有的container view都用了这个模式
    观察者模式observer,所有的UIResponder都用了这个模式。
     模板(Template)模式,所有datasource和delegate接口都是模板模式的典型应用 
     
     
     

    33. .timer的间隔周期准吗?为什么?怎样实现一个精准的timer?

    NSTimer可以精确到50-100毫秒.
    NSTimer不是绝对准确的,而且中间耗时或阻塞错过下一个点,那么下一个点就pass过去了
    展开全文
  • iOS 面试题

    2016-04-04 14:53:09
    iOS 面试题
  • 2018年末大厂面试总结,涨薪必备,19年换工作加薪,百度、腾讯、阿里等
  • iOS面试必看

    2019-07-23 09:40:05
    001_尚学堂__iOS面试题_命名规范 002_尚学堂_iOS面试题_strongweakcopy上 003_尚学堂_iOS面试题_strongweakcopy下 004_尚学堂_iOS面试题_可变属性问题 005_尚学堂_iOS面试题_selfsuper 006_...
  • IOS面试题汇总

    千次阅读 2014-02-21 20:37:28
    1.Difference between shallow copy and deep copy?
浅复制和深复制的区别?
 答案:浅层复制:只复制指向对象的指针,而不复制引用对象本身。
深层复制:复制引用对象本身。
意思就是说我有个A对象,复制一份后...

    1.Difference between shallow copy and deep copy?
浅复制和深复制的区别?

    答案:浅层复制:只复制指向对象的指针,而不复制引用对象本身。
深层复制:复制引用对象本身。
意思就是说我有个A对象,复制一份后得到A_copy对象后,对于浅复制来说,A和A_copy指向的是同一个内存资源,复制的只不过是是一个指针,对象本身资源
还是只有一份,那如果我们对A_copy执行了修改操作,那么发现A引用的对象同样被修改,这其实违背了我们复制拷贝的一个思想。深复制就好理解了,内存中存在了
两份独立对象本身。
用网上一哥们通俗的话将就是:
浅复制好比你和你的影子,你完蛋,你的影子也完蛋
深复制好比你和你的克隆人,你完蛋,你的克隆人还活着。


    2.What is advantage of categories? What is difference between implementing a category and inheritance?
类别的作用?继承和类别在实现中有何区别?
    答案:category 可以在不获悉,不改变原来代码的情况下往里面添加新的方法,只能添加,不能删除修改。
并且如果类别和原来类中的方法产生名称冲突,则类别将覆盖原来的方法,因为类别具有更高的优先级。
类别主要有3个作用:
(1)将类的实现分散到多个不同文件或多个不同框架中。
(2)创建对私有方法的前向引用。
(3)向对象添加非正式协议。
 继承可以增加,修改或者删除方法,并且可以增加属性。


    3.Difference between categories and extensions?
类别和类扩展的区别。
    答案:category和extensions的不同在于 后者可以添加属性。另外后者添加的方法是必须要实现的。
extensions可以认为是一个私有的Category。


    4.Difference between protocol in objective c and interfaces in java?
obc中的协议和java中的接口概念有何不同?

    答案:OBC中的代理有2层含义,官方定义为 formal和informal protocol。前者和Java接口一样。
informal protocol中的方法属于设计模式考虑范畴,不是必须实现的,但是如果有实现,就会改变类的属性。
其实关于正式协议,类别和非正式协议我很早前学习的时候大致看过,也写在了学习教程里
“非正式协议概念其实就是类别的另一种表达方式“这里有一些你可能希望实现的方法,你可以使用他们更好的完成工作”。
这个意思是,这些是可选的。比如我门要一个更好的方法,我们就会申明一个这样的类别去实现。然后你在后期可以直接使用这些更好的方法。
这么看,总觉得类别这玩意儿有点像协议的可选协议。"
现在来看,其实protocal已经开始对两者都统一和规范起来操作,因为资料中说“非正式协议使用interface修饰“,
现在我们看到协议中两个修饰词:“必须实现(@requied)”和“可选实现(@optional)”。


    5.What are KVO and KVC?

    答案:kvc:键 - 值编码是一种间接访问对象的属性使用字符串来标识属性,而不是通过调用存取方法,直接或通过实例变量访问的机制。
很多情况下可以简化程序代码。apple文档其实给了一个很好的例子。
kvo:键值观察机制,他提供了观察某一属性变化的方法,极大的简化了代码。
具体用看到嗯哼用到过的一个地方是对于按钮点击变化状态的的监控。
比如我自定义的一个button
[cpp] 
[self addObserver:self forKeyPath:@"highlighted" options:0 context:nil]; 
 
 
#pragma mark KVO 
 
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context 
{ 
 if ([keyPath isEqualToString:@"highlighted"] ) { 
 [self setNeedsDisplay]; 
 } 
}
    对于系统是根据keypath去取的到相应的值发生改变,理论上来说是和kvc机制的道理是一样的。
对于kvc机制如何通过key寻找到value:
“当通过KVC调用对象时,比如:[self valueForKey:@”someKey”]时,程序会自动试图通过几种不同的方式解析这个调用。首先查找对象是否带有 someKey 这个方法,如果没找到,会继续查找对象是否带有someKey这个实例变量(iVar),如果还没有找到,程序会继续试图调用 -(id) valueForUndefinedKey:这个方法。如果这个方法还是没有被实现的话,程序会抛出一个NSUndefinedKeyException异常错误。
 
(cocoachina.com注:Key-Value Coding查找方法的时候,不仅仅会查找someKey这个方法,还会查找getsomeKey这个方法,前面加一个get,或者_someKey以及_getsomeKey这几种形式。同时,查找实例变量的时候也会不仅仅查找someKey这个变量,也会查找_someKey这个变量是否存在。)
 
设计valueForUndefinedKey:方法的主要目的是当你使用-(id)valueForKey方法从对象中请求值时,对象能够在错误发生前,有最后的机会响应这个请求。这样做有很多好处,下面的两个例子说明了这样做的好处。“
来至cocoa,这个说法应该挺有道理。
因为我们知道button却是存在一个highlighted实例变量.因此为何上面我们只是add一个相关的keypath就行了,
可以按照kvc查找的逻辑理解,就说的过去了。


    6.What is purpose of delegates?
代理的作用?
    答案:代理的目的是改变或传递控制链。允许一个类在某些特定时刻通知到其他类,而不需要获取到那些类的指针。可以减少框架复杂度。
另外一点,代理可以理解为java中的回调监听机制的一种类似。


    7.What are mutable and immutable types in Objective C?
obc中可修改和不可以修改类型。

    答案:可修改不可修改的集合类。这个我个人简单理解就是可动态添加修改和不可动态添加修改一样。
比如NSArray和NSMutableArray。前者在初始化后的内存控件就是固定不可变的,后者可以添加等,可以动态申请新的内存空间。


    8.When we call objective c is runtime language what does it mean?
我们说的obc是动态运行时语言是什么意思?

    答案:多态。 主要是将数据类型的确定由编译时,推迟到了运行时。
这个问题其实浅涉及到两个概念,运行时和多态。
简单来说,运行时机制使我们直到运行时才去决定一个对象的类别,以及调用该类别对象指定方法。
多态:不同对象以自己的方式响应相同的消息的能力叫做多态。意思就是假设生物类(life)都用有一个相同的方法-eat;
那人类属于生物,猪也属于生物,都继承了life后,实现各自的eat,但是调用是我们只需调用各自的eat方法。
也就是不同的对象以自己的方式响应了相同的消息(响应了eat这个选择器)。
因此也可以说,运行时机制是多态的基础?~~~


    9.what is difference between NSNotification and protocol?
通知和协议的不同之处?

    答案:协议有控制链(has-a)的关系,通知没有。
首先我一开始也不太明白,什么叫控制链(专业术语了~)。但是简单分析下通知和代理的行为模式,我们大致可以有自己的理解
简单来说,通知的话,它可以一对多,一条消息可以发送给多个消息接受者。
代理按我们的理解,到不是直接说不能一对多,比如我们知道的明星经济代理人,很多时候一个经济人负责好几个明星的事务。
只是对于不同明星间,代理的事物对象都是不一样的,一一对应,不可能说明天要处理A明星要一个发布会,代理人发出处理发布会的消息后,别称B的
发布会了。但是通知就不一样,他只关心发出通知,而不关心多少接收到感兴趣要处理。
因此控制链(has-a从英语单词大致可以看出,单一拥有和可控制的对应关系。


    10.What is push notification?
什么是推送消息?


     

    Provider是指某个iPhone软件的Push服务器,APNS是Apple Push Notification Service的缩写,是苹果的服务器。

     

    上图可以分为三个阶段:

    第一阶段:应用程序把要发送的消息、目的iPhone的标识打包,发给APNS。 

    第二阶段:APNS在自身的已注册Push服务的iPhone列表中,查找有相应标识的iPhone,并把消息发送到iPhone。 

    第三阶段:iPhone把发来的消息传递给相应的应用程序,并且按照设定弹出Push通知。

     

    11.Polymorphism?
关于多态性

    答案:多态,子类指针可以赋值给父类。
这个题目其实可以出到一切面向对象语言中,
因此关于多态,继承和封装基本最好都有个自我意识的理解,也并非一定要把书上资料上写的能背出来。
最重要的是转化成自我理解。


    12.Singleton?
对于单例的理解

    答案:11,12题目其实出的有点泛泛的感觉了,可能说是编程语言需要或是必备的基础。
基本能用熟悉的语言写出一个单例,以及可以运用到的场景或是你编程中碰到过运用的此种模式的框架类等。
进一步点,考虑下如何在多线程访问单例时的安全性。


    13.What is responder chain?
说说响应链

    答案: 事件响应链。包括点击事件,画面刷新事件等。在视图栈内从上至下,或者从下之上传播。
可以说点事件的分发,传递以及处理。具体可以去看下touch事件这块。因为问的太抽象化了
严重怀疑题目出到越后面就越笼统。


    14.Difference between frame and bounds?
frame和bounds有什么不同?

    答案:frame指的是:该view在父view坐标系统中的位置和大小。(参照点是父亲的坐标系统)
bounds指的是:该view在本身坐标系统中 的位置和大小。(参照点是本身坐标系统)


    15.Difference between method and selector?
方法和选择器有何不同?

    答案:selector是一个方法的名字,method是一个组合体,包含了名字和实现.
详情可以看apple文档。


    16.Is there any garbage collection mechanism in Objective C.?
OBC的垃圾回收机制?

    答案: OBC2.0有Garbage collection,但是iOS平台不提供。
一般我们了解的objective-c对于内存管理都是手动操作的,但是也有自动释放池。
但是差了大部分资料,貌似不要和arc机制搞混就好了。
求更多~~


    17.NSOperation queue?

    答案:存放NSOperation的集合类。
操作和操作队列,基本可以看成java中的线程和线程池的概念。用于处理ios多线程开发的问题。
网上部分资料提到一点是,虽然是queue,但是却并不是带有队列的概念,放入的操作并非是按照严格的先进现出。
这边又有个疑点是,对于队列来说,先进先出的概念是Afunc添加进队列,Bfunc紧跟着也进入队列,Afunc先执行这个是必然的,
但是Bfunc是等Afunc完全操作完以后,B才开始启动并且执行,因此队列的概念离乱上有点违背了多线程处理这个概念。
但是转念一想其实可以参考银行的取票和叫号系统。
因此对于A比B先排队取票但是B率先执行完操作,我们亦然可以感性认为这还是一个队列。
但是后来看到一票关于这操作队列话题的文章,其中有一句提到
“因为两个操作提交的时间间隔很近,线程池中的线程,谁先启动是不定的。”
瞬间觉得这个queue名字有点忽悠人了,还不如pool~
综合一点,我们知道他可以比较大的用处在于可以帮组多线程编程就好了。


    18.What is lazy loading?

    答案:懒汉模式,只在用到的时候才去初始化。
也可以理解成延时加载。
我觉得最好也最简单的一个列子就是tableView中图片的加载显示了。
一个延时载,避免内存过高,一个异步加载,避免线程堵塞。


    19.Can we use two tableview controllers on one viewcontroller?
是否在一个视图控制器中嵌入两个tableview控制器?

    答案:一个视图控制只提供了一个View视图,理论上一个tableViewController也不能放吧,
只能说可以嵌入一个tableview视图。当然,题目本身也有歧义,如果不是我们定性思维认为的UIViewController,
而是宏观的表示视图控制者,那我们倒是可以把其看成一个视图控制者,它可以控制多个视图控制器,比如TabbarController
那样的感觉。


    20.Can we use one tableview with two different datasources? How you will achieve this?
一个tableView是否可以关联两个不同的数据源?你会怎么处理?

    答案:首先我们从代码来看,数据源如何关联上的,其实是在数据源关联的代理方法里实现的。
因此我们并不关心如何去关联他,他怎么关联上,方法只是让我返回根据自己的需要去设置如相关的数据源。
因此,我觉得可以设置多个数据源啊,但是有个问题是,你这是想干嘛呢?想让列表如何显示,不同的数据源分区块显示?


    21.Object-c的类可以多重继承么?可以实现多个接口么?重写一个类的方式用继承好还是分类好?为什么?
    Objective-c只支持单继承,如果要实现多继承的话,可以通过类别和协议的方式来实现,cocoa 中所有的类都是NSObject 的子类,多继承在这里是用protocol 委托代理 来实现的。

    Objective-C的类不支持多继承。可以实现多可接口(协议)。

    Category是Objective-C的类别,是一种为现有的类添加新方法的方式。

    重写一个类的方式用继承好。(1)使用继承可以定义一个具有父类所有功能的新类,它继承了父类的这些功能,当与父类功能有所不同时候,可以在子类中将其覆盖。(2)类别中无法向类中添加新的实例变量,类别没有位置容纳实例变量。

    说明:

    类别有两个方面的局限性:第一,无法向类中添加新的实例变量。类别没有位置容纳实例变量。第二,命名冲突,即类别中的方法与现有的方法重名。当发生命名冲突时,类别具有更高的优先级。你的类别方法将完全取代初始方法,从而无法再使用初始化方法。有些编程人员再自己的类别方法中增加一个前缀,以确保不发生命名冲突。

    类别的作用:Cocoa中的类别主要用于3个目的:将类的实现分散到多个不同文件或多个不同框架中,创建对私有方法的前向引用,以及向对象添加非正式协议。



    22.#import 跟#include 又什么区别 #import<> 跟 #import""又什么区别?
    答案:@class一般用于头文件中需要声明该类的某个实例变量的时候用到,在m文 件中还是需要使用#import而#import比起#include的好处就是不会引起交叉编译。

    #import比起#include的好处就是不会引起交叉编译

    在 Objective-C中,#import 被当成 #include 指令的改良版本来使用。除此之外,#import 确定一个文件只能被导入一次,这使你在递归包含中不会出现问题

    @class一般用于头文件中需要声明该类的某个实例变量的时候用到,在m文件中还是需要使用#import

    @class就是告诉编译器有这么一个类,至于类的定义是啥不知道

    @class一般用于头文件中需要声明该类的某个实例变量的时候用到,在m文件中还是需要使用#import

     #import<> 跟 #import""又什么区别?

    “”的意思是自己创建的文件,用这个首先会在当前的目录中寻找,如果找不到就到其他的位置寻找,“”和<>是相对的一个是自己创建的文件一个是系统的文件



    23.类变量的@protected ,@private,@public,@package声明各有什么含义?

    @protected —Methods defined in the class and any subclasses can directly access the instance variables that follow.This is the default case.

    该类和所有的子类中的方法可以直接访问这样的变量,这是默认的

    @private —Methods defined in the class can directly access the instance variables that follow, but subclasses cannot.

    该类中的方法可以访问这样的变量,子类不可以。

    @public —Methods defined in the class and any other classes or modules can di- rectly access the instance variables that follow.

    除了自己和子类中的方法外,也可以被其他类或者其他模块中的方法所访问。开放性最大。

    @package —For 64-bit images, the instance variable can be accessed anywhere within the image that implements the class.

    对于64位图像,这样的成员变量可以在实现这个类的图像中随意访问。



    24.id 声明的对象有什么特性?
    答案:id是个很重要的类型,是个可以指向任何类型的指针或者可以理解为指向任何未知类型的指针。

    id任意对象类型的,不能表示基本对象类型。id类型是通用指针类型,因为通过指针,也就是内存地址来引用对象,所以可以自由地将它们在id变量之间来回赋值。因此,返回id类型值的方法是返回指向内存中某对象的指针。然后可以将该值赋给任何对象变量。因为无论在哪里,对象总是携带它的isa成员。所以即使将它存储在id类型的通用对象变量中,也总是可以确定它的类。


    25.MVC是什么?有什么特性?为什么在iPhone上被广泛运用?
    答案:MVC设计模式考虑三种对象:模型对象、视图对象、和控制器对象。模型对象代表 特别的知识和专业技能,它们负责保有应用程序的数据和定义操作数据的逻辑。视图对象知道如何显示应用程序的模型数据,而且可能允许用户对其进行编辑。控制 器对象是应用程序的视图对象和模型对象之间的协调者。


    26.对于语句NSString* testObject = [[NSData alloc] init];testObject 在编译时和运行时分别是什么类型的对象?

    编译的时候是NSString 运行时候是NSdata 会有警告。

    27.什么是安全释放?

    if(object){[object release]; object = nil;}

    28.为什么有些4.0独有的objective-c 函数在3.1上运行时会报错.而4.0独有的类在3.1上分配内存时不会报错?分配的结果是什么?

    29.为什么4.0独有的c函数在3.1的机器上运行不会报错(在没有调用的情况下?)而4.0独有的类名在3.1的机器上一运行就报错?

    30.异常exception 怎么捕获?不同的CPU结构上开销怎样?C中又什么类似的方法?

    @try {

            <#statements#>

        }

        @catch (NSException *exception) {

            <#handler#>

        }

        @finally {

            <#statements#>

        }


    31.property中属性retain,copy,assgin的含义分别是什么?有什么区别?将其转换成get/set方法怎么做?有什么注意事项?

    retain

    1. - (void)setInstance:(id)instance{
          if (_instance != instance) {
              [_instance release];
              _instance = [instance retain];
          }
      }

    copy

     
    1. - (void)setInstance:(id)instance{
          if (_instance != instance) {
              [_instance release];
              _instance = [instance copy];
          }
      }

    assgin


    1. - (void)setInstance:(id)instance{
          if (_instance != instance) {
              _instance = instance;
          }
      }

    assign用于简单数据类型,如NSInteger,double,bool,

    retain和copy用于对象,

    copy其实是建立了一个相同的对象,而retain不是:

    比如一个NSString 对象,地址为0×1111 ,内容为@”STR”,Copy 到另外一个NSString之后,地址为0×2222 ,内容相同。

    新的对象retain为1 ,旧有对象没有变化retain到另外一个NSString 之后,地址相同(建立一个指针,指针拷贝),内容当然相同,这个对象的retain值+1。

    总结:retain 是指针拷贝,copy 是内容拷贝。

    Assign setter(完整代码)

    -(void) setString:(NSString*)newString {

        // 没有强链接,旧值被改变了

        self->string = newString; //直接指定

    }

     

    retainsetter(完整代码)

    // ------ 不正确的实现 ------

    -(void) setString:(NSString*)newString

    {

        self->string = [newString retain];

        // 错误!内存泄露,没有引用指向旧的"string",因此再也无法释放

    }

    -(void) setString:(NSString*)newString

    {

        [self->string release];

        self->string = [newString retain];

        // 错误!如果 newString == string(这是可能的),

        //newString引用是 1,那么在 [self->string release]之后

        // 使用 newString 就是非法的,因为此时对象已经被释放

    }

    -(void) setString:(NSString*)newString

    {

        if (self->string != newString)

            [self->string release]; //正确:给 nil 发送 release是安全的

        self->string = [newString retain]; //错误!应该在 if 里面

        // 因为如果 string == newString,

        // 计数器不会被增加

    }

    // ------ 正确的实现 ------

    // 最佳实践:C++程序员一般都会"改变前检查"

    -(void) setString:(NSString*)newString

    {

        // 仅在必要时修改

        if (self->string != newString) {

            [self->string release]; //释放旧的

            self->string = [newString retain]; // retain新的

        }

    }

    // 最佳实践:自动释放旧值

    -(void) setString:(NSString*)newString

    {

        [self->stringautorelease]; //即使 string == newString也没有关系,

        // 因为release 是被推迟的

        self->string = [newString retain];

        //... 因此这个 retain 要在 release之前发生

    }

    // 最佳实践:先 retain在 release

    -(void) setString:(NSString*)newString

    {

        [self->newString retain]; //引用计数器加 1(除了 nil)

        [self->string release]; // release时不会是 0

        self->string = newString; //这里就不应该再加 retain 了

    }

     

    copy setter(完整代码)

    无论是典型的误用还是正确的解决方案,都和前面使用 retain指定一样,只不过把 retain换成 copy。

     



    32.委托是什么?委托的property声明用什么属性?为什么?

    委托:一个对象保存另外一个对象的引用,被引用的对象实现了事先确定的协议,该协议用于将引用对象中的变化通知给被引用对象。

         

           委托和委托方双方的property声明属性都是assign而不是retain

    为了避免循环引用造成的内存泄露。

          循环引用的问题这样理解:

           比如在main函数中创建了两个类的对象AB,现在引用计数都是1。现在让AB互相引用(A有一个属性是B对象,属性说明是retainB有一个属性是A对象,属性说明是retain),现在两个对象的引用计数都增加了1,都变成了2

      现在执行[A release]; [B release]; 此时创建对象的main函数已经释放了自己对对象的所有权,但是此时AB的引用计数都还是1,因为他们互相引用了。

      这时你发现AB将无法释放,因为要想释放A必须先释放B,在Bdealloc方法中再释放A。同理,要想释放B必须先释放A,在Adealloc方法中再释放B。所以这两个对象将一直存在在内存中而不释放。这就是所谓的循环引用的问题。

      要想解决这个问题,一般的方法可以将引用的属性设置为assign,而不是retain来处理。



    34.Cocoa中有虚基类的概念么?怎么简洁的实现?

    没有,Cocoa框架包含两个核心框架:Foundation和Application Kit (UIKit) 框架。在iOS中没有多继承,而<a target=_blank target="_blank" class="inner-link decor-none" href="http://zhidao.baidu.com/search?word=%E8%99%9A%E5%9F%BA%E7%B1%BB&fr=qb_search_exp&ie=utf8" rel="nofollow" style="color: rgb(106, 57, 6); text-decoration: none; ">虚基类</a>是解决c++中<a target=_blank target="_blank" class="inner-link decor-none" href="http://zhidao.baidu.com/search?word=%E5%A4%9A%E9%87%8D%E7%BB%A7%E6%89%BF&fr=qb_search_exp&ie=utf8" rel="nofollow" style="color: rgb(106, 57, 6); text-decoration: none; ">多重继承</a>问题而产生的。

    35.自动释放池跟GC(垃圾回收)有什么区别?iPhone上有GC么?[pool release] 和[pool drain]有什么区别?
    iPhone上没有GC。iPhone开发的时候没有垃圾回收机制。
    在垃圾回收环境中,release是一个空操作。因此,NSAutoreleasePool提供了drain方法,在引用计数环境中,该方法的作用等同于调用release,但在垃圾回收环境中,它会触发垃圾回收(如果自上次垃圾回收以来分配的内存大于当前的阈值)。因此,在通常情况下,您应该使用drain而不是release来销毁自动释放池。


    36.
    for(int index = 0; index < 20; index ++){
    NSString *tempStr = @”tempStr”;
    NSLog(tempStr);
    NSNumber *tempNumber = [NSNumber numberWithInt:2];
    NSLog(tempNumber);
    }
    这段代码有什么问题.?会不会造成内存泄露(多线程)?在内存紧张的设备上做大循环时自动释放池是写在循环内好还是循环外好?为什么?

    37.内存管理的几条原则时什么?按照默认法则.那些关键字生成的对象需要手动释放?在和property结合的时候怎样有效的避免内存泄露?

    归结起来就一句话:如果使用了new、alloc或copy获得一个对象,则必须释放或自动释放该对象。谁申请谁释放

    38.在一个对象释放前.如果他被加到了notificationCenter 中.不在notificationcenter中remove这个对象可能会出现什么问题?


    39.怎样实现一个 singleton的类.给出思路。

    static RootViewController *sharedRootController = nil;

    +(RootViewController *) sharedController{ 
     
      @synchronized(self)
      {     
         if (sharedRootController == nil)
         {          
            sharedRootController = [[[self alloc] init] autorelease];       
         }   
      }
      return sharedRootController; 
    }


    40.什么是序列化或者Acrchiving,可以用来做什么,怎样与copy结合,原理是什么?.

    将对象的状态信息转换为可以存储或传输的形式的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区。

    41. 线程与进程的区别和联系?
    答案: 进程和线程都是由操作系统所体会的程序运行的基本 单元,系统利用该基本单元实现系统对应用的并发性。
    程和线程的主要差别在于它们是不同的操作系统资源 管理方式。进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变 量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一 些。但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。


    42.在iphone上有两件事情要做,请问是在一个线程里按顺序做效率高还是两个线程里做效率高?为什么?

    看具体问题。如果是有前后依赖关系 还是单一线程。如果可以并发的事件,就多线程

    43.runloop是什么?在主线程中的某个函数里调用了异步函数,怎么样block当前线程,且还能响应当前线程的timer事件,touch事件等.

    44.ios平台怎么做数据的持久化?coredata和sqlite有无必然联系?coredata是一个关系型数据库吗?
    iOS中可以有四种持久化数据的方式: 属性列表、对象归档、SQLite3和Core Data;core data可以使你以图形界面的方式快速的定义app的数据模型,同时在你的代码中容易获取到它。core data提供了基础结构去处理常用的功能,例如保存,恢复,撤销和重做,允许你在app中继续创建新的任务。在使用core data的时候,你不用安装额外的数据库系统,因为core data使用内置的sqlite数据库。core data将你app的模型层放入到一组定义在内存中的数据对象。core data会追踪这些对象的改变,同时可以根据需要做相反的改变,例如用户执行撤销命令。当core data在对你app数据的改变进行保存的时候,core data会把这些数据归档,并永久性保存。
    mac os x中sqlite库,它是一个轻量级功能强大的关系数据引擎,也很容易嵌入到应用程序。可以在多个平台使用,sqlite是一个轻量级的嵌入式sql数据库编程。与core data框架不同的是,sqlite是使用程序式的,sql的主要的API来直接操作数据表。
    Core Data不是一个关系型数据库,也不是关系型数据库管理系统(RDBMS)。虽然Core Dta支持SQLite作为一种存储类型,但它不能使用任意的SQLite数据库。Core Data在使用的过程种自己创建这个数据库。Core Data支持对一、对多的关系。


    45.阐述一个nil对象从interface bulider产生,到载入程序运行空间,最后被释放时所经历的生命周期.

    47.kvc是什么?kvo是什么?有什么特性?

    看文章:http://blog.csdn.net/kevinpake/article/details/14434377

    48.响应者链是什么?

    UIResponder;

    49.unix上进程怎么通信?

       UNIX主要支持三种通信方式:

       1. 基本通信:主要用来协调进程间的同步和互斥

       (1)锁文件通信

         通信的双方通过查找特定目录下特定类型的文件(称锁文件)来完成进程间  对临界资源访问时的互斥;例如进程p1访问一个临界资源,首先查看是否有一个特定类型文件,若有,则等待一段时间再查找锁文件。

       (2)记录锁文件

       2. 管道通信:适应大批量的数据传递

       3. IPC    :适应大批量的数据传递

     

    50.timer的间隔周期准吗?为什么?怎样实现一个精准的timer?

     

    IOS中可以使用"mach_absolute_time"获取到CPU的tickcount的计数值,可以通过"mach_timebase_info"函数获取到纳秒级的精确度 代码如下: uint64t start = 0; uint64t end = 0; uint64_t elapsed = 0;

    mach_timebase_info_t timeBaseInfo = mach_timebase_info(info);
    start = mach_absolute_time();
    
    <span class="comment" style="color: rgb(153, 153, 136); font-style: italic; ">// dosomething</span>
    <span class="comment" style="color: rgb(153, 153, 136); font-style: italic; ">// .....</span>
    
    <span class="keyword" style="font-weight: bold; ">end</span> = mach_absolute_time();
    elapsed = <span class="keyword" style="font-weight: bold; ">end</span> - start;
    
    <span class="comment" style="color: rgb(153, 153, 136); font-style: italic; ">// convert to nanoseconds</span>
    uint64_t elapsedNanoSeconds = elapsed * sTimebaseInfo<span class="variable" style="color: teal; ">.numer</span> / sTimebaseInfo<span class="variable" style="color: teal; ">.denom</span>;
    

    但是CPU线程之间的调度肯定要花费时间,所以只能尽可能的精确。

    51.UIscrollVew用到了什么设计模式?还能再foundation库中找到类似的吗?(答案众多,不知道哪个是对的~~)

    模板(Template)模式,所有datasource和delegate接口都是模板模式的典型应用,

    组合模式composition,所有的containerview都用了这个模式

    观察者模式observer,所有的UIResponder都用了这个模式。

     

    52如果要开发一个类似eclipse的软件,支持插件结构。且开放给第三方开发。你会怎样去设计它?(大概思路)

     

    53. 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].

     

    54. 以下为Windows NT下的32位C++程序,请计算sizeof的值

voidFunc ( char str[100] )  
{  
  sizeof( str ) =?  
}  
void *p = malloc( 100 ); 
sizeof ( p ) = ?

    答案:这题 很常见了,Func( char str[100] )函数中数组名作为函数形参时,在函数体内,数组名失去了本身的内涵,仅仅只是一个指针;在失去其内涵的同时,它还失去了其常量特性,可以作自增、自减等操作,可以被修改。Windows NT 32位平台下,指针的长度(占用内存的大小)为4字节,故sizeof( str ) 、sizeof( p ) 都为4。

     

    55.- (void)*getNSString(const NSString *inputString)

    {    inputString =@"This is a main test\n";

         return ;}

    -main(void)

    {NSString *a=@"Main";

    NSString *aString = [NSStringstringWithString:@"%@",getNSString(a)];

    NSLog(@"%@\n", aString);}

    最后问输出的字符串:NULL,output在 函数返回后,内存已经被释放。

     

    56.列举几种进程的同步机制,并比较其优缺点。

    答案:  原子操作信号量机制    自旋锁    管程,会合,分布式系统 


    进程之间通信的途径

    答案:共享存储系统消息传递系统管道:以文件系统为基础

    进程死锁的原因

    答案:资源竞争及进程推进顺序非法

    死锁的4个必要条 件

    答案:互斥、请求保持、不可剥夺、环路

    死锁的处理

    答案:鸵鸟策略、预防策略、避免策略、检测与解除死锁

     

    57.堆和栈的区别

    管理方式:对于栈来讲,是由编译器自动管理,无需我们手工控制;对于堆来说,释放工作由程序员控制,容易产生memory leak。

    申请大小:
栈:在Windows下,栈是向低地址扩展的数据结构,是一块连续的内存的区域。这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的,在WINDOWS下,栈的大小是2M(也有的说是1M,总之是一个编译时就确定的常数),如果申请的空间超过栈的剩余空间时,将提示overflow。因此,能从栈获得的空间较小。
堆:堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。

    碎片问题:对于堆来讲,频繁的new/delete势必会造成内存空间的不连续,从而造成大量的碎片,使程序效率降低。对于栈来讲,则不会存在这个 问题,因为栈是先进后出的队列,他们是如此的一一对应,以至于永远都不可能有一个内存块从栈中间弹出

    分配方式:堆都是动态分配的,没有静态分配的堆。栈有2种分配方式:静态分配和动态分配。静态分配是编译器完成的,比如局部变量的分配。动态分配由alloca函数进行分配,但是栈的动态分配和堆是不同的,他的动态分配是由编译器进行释放,无需我们手工实现。

    分配效率:栈是机器系统提供的数据结构,计算机会在底层对栈提供支持:分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行,这就决定了栈的效率比较高。堆则是C/C++函数库提供的,它的机制是很复杂的。

     

    58.什么是键-值,键路径是什么?

    模型的性质是通过一个简单的键(通常是个字符串)来指定的。视图和控制器通过键来查找相应的属性值。在一个给定的实体中,同一个属性的所有值具有相同的数据类型。键-值编码技术用于进行这样的查找—它是一种间接访问对象属性的机制。

    键路径是一个由用点作分隔符的键组成的字符串,用于指定一个连接在一起的对象性质序列。第一个键的
性质是由先前的性质决定的,接下来每个键的值也是相对于其前面的性质。键路径使您可以以独立于模型
实现的方式指定相关 对象的性质。通过键路径,您可以指定对象图中的一个任意深度的路径,使其指向相
关对象的特定属性。

     

    59.c和obj-c如何混用

    1)obj-c的编译器处理后缀为m的文件时,可以识别obj-c和c的代码,处理mm文件可以识别obj-c,c,c++代码,但cpp文件必须只能用c/c++代码,而且cpp文件include的头文件中,也不能出现obj- c的代码,因为cpp只是cpp
2) 在mm文件中混用cpp直接使用即可,所以obj-c混cpp不是问题
3)在cpp中混用obj- c其实就是使用obj-c编写的模块是我们想要的。
如果模块以类实现,那么要按照cpp class的标准写类的定义,头文件中不能出现obj-c的东西,包括#import cocoa的。实现文件中,即类的实现代码中可以使用obj-c的东西,可以import,只是后缀是mm。
如果模块以函数实现,那么头文件要按 c的格式声明函数,实现文件中,c++函数内部可以用obj-c,但后缀还是mm或m。

总结:只要cpp文件和cpp include的文件中不包含obj-c的东西就可以用了,cpp混用obj-c的关键是使用接口,而不能直接使用实现代码,实际上cpp混用的是 obj-c编译后的o文件,这个东西其实是无差别的,所以可以用。obj-c的编译器支持cpp.

     

    60.目标-动作机制

    目标是动作消息的接收者。一个控件,或者更为常见的是它的单元,以插座变量(参见"插座变量"部分)
的形式保有其动作消息的目标。

    动作是控件发送给目标的消息,或者从目标的角度看,它是目标为了响应动作而实现的方法。

    程序需要某些机制来进行事件和指令的翻译。这个机制就是目标-动作机制。

     

    61.cocoatouch框架

    iPhoneOS 应用程序的基础Cocoa Touch 框架重用了许多 Mac 系统的成熟模式,但是它更多地专注于触摸的接口和优化。UIKit 为您提供了在 iPhone OS 上实现图形,事件驱动程序的基本工具,其建立在和 Mac OS X 中一样的 Foundation 框架上,包括文件处理,网络,字符串操作等。

    CocoaTouch 具有和 iPhone 用户接口一致的特殊设计。有了 UIKit,您可以使用 iPhone OS 上的独特的图形接口控件,按钮,以及全屏视图的功能,您还可以使用加速仪和多点触摸手势来控制您的应用。

    各色俱全的框架 除了UIKit 外,Cocoa Touch 包含了创建世界一流iPhone 应用程序需要的所有框架,从三维图形,到专业音效,甚至提供设备访问 API 以控制摄像头,或通过 GPS 获知当前位置。Cocoa Touch 既包含只需要几行代码就可以完成全部任务的强大的 Objective-C 框架,也在需要时提供基础的 C 语言 API 来直接访问系统。这些框架包括:

    CoreAnimation

    通过 CoreAnimation,您就可以通过一个基于组合独立图层的简单的编程模型来创建丰富的用户体验。

    CoreAudio

    CoreAudio 是播放,处理和录制音频的专业技术,能够轻松为您的应用程序添加强大的音频功能。

    CoreData

    提供了一个面向对象的数据管理解决方案,它易于使用和理解,甚至可处理任何应用或大或小的数据模型。

    功能列表:框架分类

    下面是 CocoaTouch 中一小部分可用的框架:

    •   音频和视频

    •   Core Audio

    •   OpenAL

    •   Media Library

    •   AV Foundation

    •   数据管理

    •   Core Data

    •   SQLite

    •   图形和动画

    •   Core Animation

    •   OpenGL ES

    •   Quartz 2D

    •   网络/li>

    •   Bonjour

    •   WebKit

    •   BSD Sockets

    •   用户应用

    •   Address Book

    •   Core Location

    •   Map Kit

    •   Store Kit

     

    62.objc的内存管理

    如果您通过分配和初始化(比如[[MyClass alloc] init])的方式来创建对象,您就拥
有这个对象,需要负责该对象的释放。这个规则在使用NSObject的便利方法new 时也同样适用.

    如果您拷贝一个对象,您也拥有拷贝得到的对象,需要负责该对象的释放.

    如果您保持一个对象,您就部分拥有这个对象,需要在不再使用时释放该对象。

    如果您从其它对象那里接收到一个对象,则您不拥有该对象,也不应该释放它(这个规则有少数
的例外,在参考文档中有显式的说明)。

     

    63.自动释放池是什么,如何工作

     当您向一个对象发送一个autorelease消息时,Cocoa就会将该对 象的一个引用放入到最新的自动释放池。它仍然是个正当的对象,因此自动释放池定义的作用域内的其它对象可以向它发送消息。当程序执行到作用域结束的位置时,自动释放池就会被释放,池中的所有对象也就被释放。

    1. ojc-c 是通过一种"referringcounting"(引用计数)的方式来管理内存的, 对象在开始分配内存(alloc)的时候引用计数为一,以后每当碰到有copy,retain的时候引用计数都会加一, 每当碰到release和autorelease的时候引用计数就会减一,如果此对象的计数变为了0, 就会被系统销毁.
2. NSAutoreleasePool 就是用来做引用计数的管理工作的,这个东西一般不用你管的.
3. autorelease和release没什么区别,只是引用计数减一的时机不同而已,autorelease会在对象的使用真正结束的时候才做引用计数减一.

     

    64.类工厂方法是什么

     类工厂方法的实现是为了向客户提供方便,它们将分配和初始化合在一个步骤中, 返回被创建的对象,并
进行自动释放处理。这些方法的形式是+ (type)className...(其中 className不包括任何前缀)。

    工厂方法可能不仅仅为了方便使用。它们不但可以将分配和初始化合在一起,还可以为初始化过程提供对
象的分配信息。

    类工厂方法的另一个目的是使类(比如NSWorkspace)提供单件实例。虽 然init...方法可以确认一
个类在每次程序运行过程只存在一个实例,但它需要首先分配一个“生的”实例,然后还必须释放该实例。
工厂 方法则可以避免为可能没有用的对象盲目分配内存。

     

    65.单件实例是什么

    Foundation和Application Kit 框架中的一些类只允许创建单件对象,即这些类在当前进程中的唯一实例。举例来说,NSFileManager和NSWorkspace 类在使用时都是基于进程进行单件对象的实例化。当向这些类请求实例的时候,它们会向您传递单一实例的一个引用,如果该实例还不存在,则首先进行实例的分配和初始化。 单件对象充当控制中心的角色,负责指引或协调类的各种服务。如果类在概念上只有一个实例(比如
NSWorkspace),就应该产生一个单件实例,而不是多个实例;如果将来某一天可能有多个实例,您可
以使用单件实例机制,而不是工厂方法或函数。

     

    66.动态绑定—在运行时确定要调用的方法

    动态绑定将调用方法的确定也推迟到运行时。在编译时,方法的调用并不和代码绑定在一起,只有在消实发送出来之后,才确定被调用的代码。通过动态类型和动态绑定技术,您的代码每次执行都可以得到不同的结果。运行时因子负责确定消息的接 收者和被调用的方法。运行时的消息分发机制为动态绑定提供支持。当您向一个动态类型确定了的对象发送消息时,运行环境系统会通过接收者的isa指针定位对象的类,并以此为起点确定被调用的方法,方法和消息是动态绑定的。而且,您不必在Objective-C 代码中做任何工作,就可以自动获取动态绑定的好处。您在每次发送消息时,

    
特别是当消息的接收者是动态类型已经确定的对象时,动态绑定就会例行而 透明地发生。

     

    67.obj-c的优缺点

    objc优点:
  1)Cateogies 
  2) Posing 
  3) 动态识别
  4) 指标计算 
  5)弹性讯息传递
  6) 不是一个过度复杂的 C 衍生语言
  7) Objective-C 与 C++ 可混合编程


    缺点: 
  1) 不支援命名空間 
  2)  不支持运算符重载

      3) 不支持多重继承

      4) 使用动态运行时类型,所有的方法都是函数调用,所以很多编译时优化方法都用不到。(如内联函数等),性能低劣。

     

    68.readwrite,readonly,assign,retain,copy,nonatomic 属性的作用?

    @property是 一个属性访问声明,扩号内支持以下几个属性:
1,getter=getterName,setter=setterName,设置setter与 getter的方法名
2,readwrite,readonly,设置可供访问级别
2,assign,setter方法直接赋值,不进行 任何retain操作,为了解决原类型与环循引用问题
3,retain,setter方法对参数进行release旧值再retain新值,所有 实现都是这个顺序(CC上有相关资料)
4,copy,setter方法进行Copy操作,与retain处理流程一样,先旧值release,再 Copy出新的对象,retainCount为1。这是为了减少对上下文的依赖而引入的机制。
5,nonatomic,非原子性访问,不加同步, 多线程并发访问会提高性能。注意,如果不加此属性,则默认是两个访问方法都为原子型事务访问。锁被加到所属对象实例级(我是这么理解的…)。

     

    69.ViewController的 didReceiveMemoryWarning 是在什么时候被调用的?(87题)

    70.谈谈你对ARC 的认识和理解?

     

    71.  ObjC中,与alloc语义相反的方法是dealloc还是release?与retain语义相反的方法是dealloc还是release,为什么?需要与alloc配对使用的方法是dealloc还是release,为什么?

    alloc与dealloc语意相反,alloc是创建变量,dealloc是释放变量。 retain 对应release,retain 保留一个对象。调用之后,变量的计数加1。或许不是很明显,在这有例为证:                 

    - (void)setName : (NSString*) name {

        [name retain];

        [myname release];

        myname = name; }

    我们来解释一下:设想,用户在调用这个函数的时候,他注意了内存的管理,所以他小心的写了如下代码:

    NSString* newname = [[NSString alloc] initWithString: @"John"];

    [aClasssetName: newname];

    [newnamerelease];

    我们来看一看newname的计数是怎么变化的。首先,它被alloc,count = 1; 然后,在setName中,它被retain,count = 2; 最后,用户自己释放newname,count= 1,myname指向了newname。这也解释了为什么需要调用[myname release]。我们需要在给myname赋新值的时候,释放掉以前老的变量。retain 之后直接dealloc对象计数器没有释放。alloc 需要与release配对使用,因为alloc 这个函数调用之后,变量的计数加1。所以在调用alloc 之后,一定要调用对应的release。另外,在release一个变量之后,他的值仍然有效,所以最好是后面紧接着再var = nil。

     

    72.  在一个对象的方法里面:

    self.name<http://self.name/> = “object”;

    name =”object”

    有什么不同?

     

     73.  这段代码有什么问题:

    @implementation Person

    - (void)setAge:(int)newAge {

    self.age = newAge;

    }

    @end

     

     74.  什么是retaincount?

     

     75.  以下每行代码执行后,person对象的retain count分别是多少

    Person *person = [[Person alloc] init];

    [person retain];

    [person release];

    [person release];

     

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

     

    77.  定义属性时,什么情况使用copy,assign,和retain?

    assign用于简单数据类型,如NSInteger,double,bool,retain和copy用户对象,copy用于当 a指向一个对象,b也想指向同样的对象的时候,如果用assign,a如果释放,再调用b会crash,如果用copy 的方式,a和b各自有自己的内存,就可以解决这个问题。retain 会使计数器加一,也可以解决assign的问题。另外:atomic和nonatomic用来决定编译器生成的getter和setter是否为原子操作。在多线程环境下,原子操作是必要的,否则有可能引起错误的结果。加了atomic,setter函数会变成下面这样:

    if(property != newValue) {       [propertyrelease];       property = [newValueretain];   } 

     

    78. autorelease的对象是在什么时候被release的?

    答:autorelease实际上只是把对release的调用延迟了,对于每一个Autorelease,系统只是把该Object放入了当前的Autoreleasepool中,当该pool被释放时,该pool中的所有Object会被调用Release。对于每一个Runloop,系统会隐式创建一个Autoreleasepool,这样所有的releasepool会构成一个象CallStack一样的一个栈式结构,在每一个Runloop结束时,当前栈顶的Autoreleasepool会被销毁,这样这个pool里的每个Object(就是autorelease的对象)会被release。那什么是一个Runloop呢?一个UI事件,Timer call,delegate call, 都会是一个新的Runloop。那什么是一个Runloop呢?一个UI事件,Timer call,delegate call, 都会是一个新的Runloop。

     

    79.  这段代码有什么问题,如何修改

    for (int i = 0; i < someLargeNumber; i++)

    {

    NSString *string = @”Abc”;

    string = [string lowercaseString];

    string = [stringstringByAppendingString:@"xyz"];

    NSLog(@“%@”, string);

    }

     

    80. autorelease和垃圾回收机制(gc)有什么关系?IPhone OS有没有垃圾回收(gc)?

     

    81. Objective C中的protocal是什么?

    @protocal obj里面的协议就如同java里面的interface。

     

    82. Objective C中的selector 是什么?

    你可以理解 @selector()就是取类方法的编号,他的行为基本可以等同C语言的中函数指针,只不过C语言中,可以把函数名直接赋给一个函数指针,而Objective-C的类不能直接应用函数指针,这样只能做一个@selector语法来取.它的结果是一个SEL类型。这个类型本质是类方法的编号(函数地址)。

     

    83. Objective C中的category是什么?

    Objective-C提供了一个非常灵活的类(Class)扩展机制-类别(Category)。类别用于对一个已经存在的类添加方法(Methods)。你只需要知道这个类的公开接口,不需要知道类的源代码。需要注意的是,类别不能为已存在的类添加实例变量(Instance Variables)。

    子类(subclassing)是进行类扩展的另一种常用方法。与子类相比,类别最主要的优点是:系统中已经存在的类可以不需修改就可使用类别的扩展功能。

    类别的第二大优点是实现了功能的局部化封装。类别定义可以放在一个已存在的类(类A)的定义文件中(.h)。这意味着这个类别只有在类A被引用的前提下才会被外部看到。如果另一个类(类B)不需要用到类A的功能(没有包含类A的.h文件),也就不会看到依附类A存在的类别。iOS SDK中广泛运用这种类别定义法来封装功能。

     

    84. 什么是Notification?什么时候用delegate,什么时候用Notification?

    观察者模式,controller向defaultNotificationCenter添加自己的notification,其他类注册这个notification就可以收到通知,这些类可以在收到通知时做自己的操作(多观察者默认随机顺序发通知给观察者们,而且每个观察者都要等当前的某个观察者的操作做完才能轮到他来操作,可以用NotificationQueue的方式安排观察者的反应顺序,也可以在添加观察者中设定反映时间,取消观察需要在viewDidUnload跟dealloc中都要注销)。

    delegate针对one-to-one关系,并且reciever可以返回值给sender,notification可以针对one-to-one/many/none,reciever无法返回值给sender.所以,delegate用于sender希望接受到reciever的某个功能反馈值,

    notification用于通知多个object某个事件。

     

    85. 什么是KVC和KVO?Notification和KVO有什么不同?KVO在ObjC中是怎么实现的?

     

    86. ViewController 的 loadView,viewDidLoad, viewDidUnload 分别是在什么时候调用的?在自定义ViewController的时候这几个函数里面应该做什么工作?

    答: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 。

     

    87. ViewController 的didReceiveMemoryWarning 是在什么时候被调用的?UIViewController类中didReceiveMemoryWarning默认的操作是什么?

    答:默认调用[superdidReceiveMemoryWarning]

     

    88. UITableViewController 中,创建UITableViewCell时,initWithSytle:resuseIdentifier中,reuseIdentifier有什么用?简述UITableViewCell的复用原理.

    复用队列的元素增加:只有在cell被滑动出界面的时候,此cell才会被加入到复用队列中。每次在创建cell的时候,程序会首先通过调用dequeueReusableCellWithIdentifier:cellType方法,到复用队列中去寻找标示符为“cellType”的cell,如果找不到,返回nil,然后程序去通过调用[[[UITableViewCell alloc]initWithStyle:style reuseIdentifier:cellType] autorelease]来创建标示符为“cellType”的cell。

     

    89. UIView 和CALayer 有什么区别?

    两者最大的区别是,图层不会直接渲染到屏幕上。

     

    90. 以 UIView 类animateWithDuration:animations: 为例,简述UIView动画原理。


    更多3
    上一篇:NSSearchPathForDirectoriesInDomains用法下一篇:iphone 线程总结— detachNewThreadSelector的使用
    0
    展开全文
  • iOS面试题整理

    2020-11-20 17:59:12
    iOS面试题整理 在线查看地址:https://ios.nobady.cn iOS面试相关问题整理,做这个的初心是希望能巩固自己的基础知识,当然也希望能帮助更多的开发者,如发现答案不准确或者不完整的可前往 Github 提交完善。 主要从...
  • iOS面试题题库

    2014-03-12 15:15:26
    1.写一个NSString类的实现 + (id)initWithCString:(c*****t char *)nullTerminatedCString encoding:(NSStringEncoding)encoding;  + (id) stringWithCString: (c*****t char*)nullTerminatedCString  ...
  • 阿里iOS面试题

    2018-09-26 15:32:11
    阿里iOS面试题,总结了一些面试经常闻到的知识点,是可以参考,阅读以下的。
  • iOS面试题合集

    2017-11-14 16:03:08
    集很多公司面试题于一体,很有深度的一份面试题,没有答案,答案自己找
  • 经过本人最近的面试和对面试资料的一些汇总,准备记录这些面试题,以便ios开发工程师找工作复习之用,本人希望有面试经验的同学能和我同时完成这个模块,先出面试题,然后会放出答案。 1. 你使用过Objective-C的...
  • IOS面试题 ios笔试题 带答案

    千次阅读 2016-01-14 09:45:24
    自己整理的一份ios初级中级面试题 一. 1、下面那个方法不属于NSObject的内省(Introspection)方法  A. init  B. isKindOfClass  C. responseToSelector  D. isMemberOfClass 2、需要在手动管理内存分配...
  • 1.When to use NSMutableArray and when to use NSArray? 什么时候使用NSMutableArray,什么时候使用NSArray? 答案:当数组在程序运行时,需要不断变化的,使用NSMutableArray,当数组在初始化后,便不再改变的,...
  • 视频面试是通过牛客网进行的,以下是记下来的各轮面试题,对于一些iOS基础知识就不做解答了。 一面 正在跳转(iOS高级开发技术交流裙 进裙密码:123) 1、用递归写一个算法,计算从1到100的和。 func sum(value: Int...
  • ios面试题收集

    2019-04-04 01:34:32
    NULL 博文链接:https://icrwen.iteye.com/blog/1480357
  • iOS面试题汇总

    2016-06-28 07:36:53
  • ios面试题

    千次阅读 2017-04-08 13:55:00
    1.Object-c的类可以多重继承么?可以实现多个接口么?Category是什么?重写一个类的方式用继承好还是分类好?为什么?Object-c的类不可以多重继承;可以实现多个接口,通过实现多个接口可以完成C++的多重继承;...
  • IOS面试题

    2017-08-01 13:00:05
    面试题一: ios声明变量的属性关键词 @property  @property = ivar + getter + setter; “属性” (property)有两大概念:ivar(实例变量)、存取方法(accessmethod = getter + setter)。 原子性:nonatomic、...

空空如也

1 2 3 4 5 ... 20
收藏数 6,670
精华内容 2,668
关键字:

ios面试