IOS面试攻略

IOS面试攻略(1.0)  

2013-10-13 20:58:09|  分类: IOS面试 |  标签:ios知识点总汇  ios面试  |举报|字号 订阅html

 
 

来自:伊甸网java

 

 

@ios

看到这个关键字,咱们就应该想到,这是Object-C对C语言的扩展,例如@interface XXX。c++

@interface程序员

声明类web

@implementation面试

实现类objective-c

@protocol算法

声明协议sql

@optional

与@protocol配合使用,说明协议中的某个或者某几个方法能够不实现

@required

与@protocol配合使用,说明协议中的某个方法或者某几个方法必须实现

@end

与@interface ,@implementation,@protocol配合使用,表明声明或者实现结束

@encode

@encode为编译器宏,它能够将类型转换为相应的字符串(const char *)。

id

id是指向Objective-C类对象的指针,它能够声明为任何类对象的指针,当在Objective-C中使用id时,编译器会假定你知道id指向哪一个类的对象。与void*是不一样的是,void*编译器不知道也不假定指向任何类型的指针。

nil

定义为一个常量,若是一个指针的值为nil,表明这个指针没有指向任何对象。

self

在Objective-C中,关键字self与c++中this是同一律念,就是类对象自身的地址,经过self能够调用本身的实例变量和方法

Super

当子类须要调用父类的方法时,会用到Super关键字. Super指向的是父类的指针,子类重写父类的方法时,调用父类的方法是一个比较好的习惯。由于当咱们不知道父类在该方法中实现的功能时,若是不调用父类的方法,有可能咱们重写的方法会失去该功能,这是咱们不肯意看到的状况。

NSNull

NSNull是没有的意思,若是一个字典的值为NSNull,那说明与该值对应的Key是没有值的,例如Key为address,说明与address对应的是值是没有。

self super class public protected private id

[self class] [super class]  selector

objective-c runtime reference

标准用法

self = [super init]

new

1 Objective-C有一个特性,就是能够把类当成对象来发送消息,这种用法一般用于新建对像时,例如 XXX *object = [XXX new];

类方法 +

若是想声明属于类而不属于类对象的方法,用+。+用来修饰类的方法,使用+修饰的类方法,是整个类的方法,不属于哪个类对象,这与C++中的static在类中使用的概念同样,

%@

在NSLog中,使用%@表示要调用对象的description方法。

概念

是一种结构,它表示对象的类型,就像int与 char 同样,也能够声明类的变量(对像)

实例化

为类的对象分配内存和初始化,达到能够使用该 类对象的目的。

对象(实例)

类的实例化后的产物

消息

在 Object-C中,类的对象执行的操做,是经过给该类或者该类对象发送消息实现,如:[object func];就是给object对象发送 func消息,相似C++中的方法调用。给object对象发送func消息后,object对象查询所属类的func方法执行。

方法调度

当向一个对象发送消息时(调用方法),这个方法是怎么被调用的呢?这就依赖于方法高度程序,方法调度程序查找的方法以下:

在本类的方法中,找被调用的方法,若是找到了,就调用,若是找不到被沿着继承路径去查找,从哪一个类找到,就调用哪一个类的方法,若是到最根上的类仍是没有找到,那编译就会出错。

继承与复合

在Objective-C中支持继承,但只是支持单一继承(有且只有一个父类有),若是想使用多继承的特性,能够使用分类和协议技术。

继承是is-a,复合是has-a。复合是经过包含指向对象的指针实现的,严格意义上讲,复合是针对于对象间来讲,对于基本数据类型来讲,它们被认为是对象的一部分。

装箱与拆箱

因为NSArray,NSDirectory等类不能直接存储基本数据类型,因此要想在NSArray\NSDirectory中使用基本数据类型,就得使用装箱与拆箱。

在Objective-C中,能够使用NSNumber和NSValue来实现对数据类型的包装,NSNumber能够实现对基本数据类型的包装,NSValue能够实现对任意类型数据的包装。

将基本类型封装成对象叫装箱,从封装的对象中提取基本类型叫拆箱(取消装箱),其它语言如Java原生支持装箱与拆箱,Ojbective-C不支持自动装箱与拆箱,若是须要得须要本身来实现装箱与拆箱。

存取方法

在 使用类对象的实例变量(成员数据)时,不要直接使用对象中的实例,要使用存以方法来获取或者修改实例,既setter和getter,在 Cocoa中, 存取方法有命名习惯,咱们得符合这种习惯,以便于与其它团队成员合做。setter方法是修改或者设置实例值,命名习惯为set+实例名,例有一个类有 path实例变量,那setter命名为setPath,getter命名为Path,为何不是getPath,由于get在Cocoa中有特殊的含 义,这个含义就是带有get的方法就意味着这个方法经过形参指针(传入函数的参数指针)来返回值。咱们要遵照这个命名习惯或者说规则。

在Objective-C 2.0中加入了@property和@synthesize来代替setter和getter,这两个关键字为编译器指令。还有点表达式,存取类成员的值时,能够使用点表达式。

Object.attribute,当点表达式在=号左边时,调用的是setter方法,在=号右边时,调用的是getter方法。

@property 语法为:@property (参数) 类型 变量名.

在这里主要说明一下参数.

参数分为三种:

第一种:读写属性包括(readonly/readwrite/)

第 二种:setter属性(assign,copy,retain),assign是简单的赋值,copy是释放旧成员变量,并新分配内存地址给成 员 变量,将传入参数内容复制一份,给成员变量。retain是将传入   参数引用计数加1,而后将原有的成员变量释放,在将成员变量指向该传入参数。

第三种:与多线程有关(atomic,nonatomic).当使用多线程时,使用atomic,在不使用多线程时使用nonatomic

对象建立与初始化

在Objective-C中建立对象有两种方法,一种是[类 new];另外一种是[[类 alloc] init],这两种方法是等价的,但按惯例来说,使用[[类 alloc] init];

alloc操做是为对象分配内存空间,并将对象的数据成员都初始,int 为0,BOOL 为NO, float 为0.0等。

初始化,默认的初始化函数为init,init返回值为id,为何回返回id呢,由于要实现链式表达式,在Objective-C中叫嵌套调用。

为何要嵌套调用??由于初始化方法init返回值可能与alloc返回的对象不是同一个?为何会发生这种状况?基于类簇的初始化,由于init能够接受参数,在init内部有可能根据不一样的参数来返回不一样种类型的对象,因此最会发生上面说的状况。

在初始化时,建议使用if (self = [super init])

便利初始化

当一个类须要根据不一样的状况来初始化数据成员时,就须要便利初始化函数,与init初始化不一样的是,便利初始化函数有参数,参数个数能够有1到N个,N是类数据成员个数。

指定初始化函数:什么是指定初始化函数?在类中,某个初始化函数会被指定为指定的初始化函数,肯定指定初始化函数的规则是初始化函数中,参数最多的为指定初始化函数,

其它未被指定为指定初始化函数的初始化函数要调用指定初始化函数来实现。对于该类的子类也是同样,只要重写或者直接使用父类的指定初始化函数。上述文字有些绕,来个例子吧

@interface A{

int x;

int y;

}

-(id) init;

-(id) initWithX:(int) xValue;

-(id) initWithY:(int) yValue;

-(id) initWithXY:(int) xValue

yVal:(int) yValue;

@end

这里initWithXY被肯定为指定初始化函数。

-(id) initWithXY:(int) xValue

yVal:(int) yValue{

if (self = [super init]){

x = xValue;

y = yValue;

}

return self;

}

-(id) init{

if (self = self initWithXY:10

yVal:20){

}

return self;

}

.......

@interface B: A{

int z;

}

-(jd) initWithXY......;

@end

@implementation B

-(id) initWithXY:(int) xValue

yVal:(int) yValue{

if (self = [super initWithXY:10

yVal=20]){

z= 40;

}

return self;

}

@end

自动释放池

内存管理是软件代码中的重中之重,内存管理的好坏,直接影响着软件的稳定性。在Cocoa中,有自动释放池,这相似于C++中的智能指针。

NSObject有一个方法是autorelease,当一个对象调用这个方法时,就会将这个对象放入到自动释放池中。

drain,该方法是清空自动释放池,不是销毁它。drain方法只适用于Mac OS X 10.4以上的版本,在咱们写的代码中要使用release,release适用于全部版本。

自 动释放池是以栈的方式实现,当建立一个自动释放池A时,A被压入栈顶,这时将接入autorelease消息的对象放入A自动释放池,这时建立一 个新的 B自动释放池,B被压入栈顶,建立完成后删除B,这个接收autorelease消息的对象依然存在,由于A自动释放池依然存在。

引用计数

每一个对象都有一个与之相应的整数,称它为引用计数,当该引用计数为0时,Objective-C自动向该对象发送dealloc,以销毁该对向,与该引用计数相关的方法(消息)有下面几个

1 增长引用计数:经过alloc,new,copy建立一个对象时,该对象的引用计数加1(其实就是1,由于以前为0)

2 增长引用计数: retain

3 减小引用计数: release

局部分配内存(临时对象):

1 若是使用alloc,new,copy建立对象,则须要主动调用对象的release方法

2 若是使用非alloc,new,copy建立对象,咱们认为该对象引用计数为1,并已经加入了自动释放池,咱们不须要主动的调用对象的release方法。

拥有对象(在类中以成员的方法存在):

1 若是使用alloc,new,copy建立对象,则须要在dealloc方法中,释放该对象

2 若是使用非alloc,new,copy建立对象,则在拥有该对象时,保留该对象(执行retain方法),在dealloc方法中,释放该对象。

dealloc

当对象的引用计数为0时,Objective-C会自动发送对象的dealloc消息(自动调用对象的dealloc方法,相似于C++的析构函数),因此咱们能够本身重写dealloc方法,来实现类里的对其它使用资源的释放工做。

注意:不要直接在代码中显示调用dealloc方法。

垃圾回收

在Objective-C 2.0中引入了垃圾回收机制(自动管理内存),在工程设置里设置Objective-C Garbage Collection为Required[-fobjc-gc-only]就能够使用垃圾回收机制。

启用垃圾回收机制后,一般的内存管理命令都变成了空操做指令,不执行任何操做。

Objective-C的垃圾回收机制是一种继承性的垃圾回收器,垃圾回收器按期检查变量和对象以及他们之间的指针,当发现没有任何变量指向对象时,就将该对象视为被丢弃的垃圾。因此在不在使用一个对象时,将指针他的指针设置为nil,这时垃圾回收器就会清理该对象。

注意:若是开发iphone软件,则不能使用垃圾回收。在编写iPhone软件时,Apple公司建议不要在本身的代码中使用autorelease方法,而且不要使用建立自动释放对象的函数。

类别

什么是类别?类别是一种为现有类添加新方法的方式。

为何使用类别或者说使用类别的目的是什么?有如下三点:

第一,能够将类的实现分散到多个不一样的文件或多个不一样的框架中。

若是一个类须要实现不少个方法,咱们能够将方法分类,把分好的类造成类别,能够有效的管理和驾驭代码。

第二,建立对私有方法的前向引用。

第三,向对象添加非正式协议。

委托

委托的意思就是你本身想作某事,你本身不作,你委托给别人作。

在Ojbective-C中,实现委托是经过类别(或非正式协议)或者协议来实现。

举 个例子:Apple要生产iPhone,Apple本身不生产(种种缘由,其中之一就是在中国生产成本低,他们赚的银子多),Apple委托富士 康来生 产,原本富士康原来不生产iPhone,如今要生产了,因此他得本身加一个生产iPhone的生产线(类别,增长生产iPhone方法),这就是经过类别 来实现委托。下面用代码来讲明这个例子。

.....

Apple *apple = [[Apple alloc ] init];

Foxconn *fox = [[Foxconn alloc] init];

[apple setDelegate:fox];

[apple produceIPhone];

........

@implementation Apple

-(...) setDelegate:(id) x{

delegate  = x; //! 将委托的生产对象指定为x

}

-(...) produceIPhone{

[delegate produceIPhone]; //! 委托对象生产iPhone

}

@interface Foxconn : NSObject

...

@end

@interface NSObject(ProduceIPhone) //! Foxconn以前就能够生产其它产品,有过声明和定义

-(...) produceIPhone  //! 增长生产iPhone能力

@end

@implementation NSObject(ProduceIPhone)

//! 生产iPhone

-(...) produceIPhone{

......

}

@end

非正式协议

建立一个NSObject的类别, 称为建立一个非正式协议。为何叫非正式协议呢?

也就是说能够实现,也能够不实现被委托的任务。

拿上面的例子来讲,Apple要求Foxconn除了能生产iPhone外,还有一个要求是在必定时间内完成.因为双方没有签合同,因此时间要求和生产要求规格都是非正式协议

选择器

选 择器就是一个方法的名称。选择器是在Objective-C运行时使用的编码方式,以实现快速查找。能够使用@selector预编译指令,获取 选择器 @selector(方法名)。NSObject提供了一个方法respondsToSelector:的方法,来访问对象是否有该方法(响应该消息)。

拿 上面的Apple请Foxconn生产iPhone为例,Apple怎么知道Foxconn有没有生产iPhone的能力呢?Apple就经过 respondsToSelector方法询问Foxconn,是否能够生产iPhone(是否能够响应produceIPhone),询问结果是能够, 那Apple就委托Foxconn生产,Foxconn就生产出来了人们比较喜欢的iPhone产品。

正式协议

与非正式协议比较而言,在Ojbective-C中,正式协议规定的全部方法必须实现。在Ojbective-C2.0中,Apple又增长了两个关键字,协议中的方法也能够不彻底实现,是哪一个关键字见关键字部份的@optional,@required。

正式协议声明以下:

@protocol XXX

-(...) func1;

-(...) func2;

@end

使用协议:

@interface Object : NSObject //! Object从NSObject派生,并遵循XXX协议,要实现func1,func2函数。

...

@end

习惯用法

分配内存和初始化

self = [super init];

对象间交互

在Objective-C中,全部对象间的交互都是经过指针实现。

快速枚举

for (Type *p in array)

注意:

Objective-C不支持多继承

objective-c只不过是拥有一些附加特性的C语言。本质上就是C语言

1.C语言使用#include通知编译器应在头文件中查询定义。objective-c也能够使用#include来实现这个目的,但你永远不可能这么作,你会用#import,它是GCC编译器提供的,#import能够保证头文件只被包含一次。

xcode会使用预编译头文件(一种通过压缩的,摘要形式的头文件),在经过#import导入这种文件时,加载速度会很是快。

2.什么是框架

框架是一种汇集在一个单元的部件集合,包含头文件,库,图像,声音文件等。苹果公 司将cocoa,Carbon,QuickTime和OpenGL 等技术 做为框架集提供。cocoa的组成部分有Foundation和Application Kit框架。还有一个支持框架的套件,包含 Core Animation和Core Image,这为Cocoa增添了多种精彩的功能。

每一个框架都是一个重要的技术集合,一般包含数十个甚至上百个头文件。每一个框架都有一个主头文件,它包含了全部框架的各个头文件。经过使用#import导入主头文件,能够使用全部框架的特性。

3.Foundation框架处理的是用户界面之下的层(layer)中得特性,例如数据结构和通讯机制。

4.NS前缀

NS这个前缀告诉你函数来自cocoa而不是其余工具包。

两个不一样事物使用相同标示符时会致使名称冲突,而前缀能够预防这个大问题。

5.BOOL类型

objective-c中得BOOL其实是一种对带符号的字符类型(signed char)的定义。它使用8位存储空间,YES为1,NO为0.

6.间接

不在代码中直接使用某个值,而是使用指向该值的指针。另外一个意思是,让别的类来完成本类的工做。

例子:

1.循环次数的变量。变量与间接

2.使用从文件读取。文件与间接

在OOP(面向对象编程)中,间接十分重要。OOP使用间接来获取数据,OOP真正的革命性就是它在调用代码中使用间接。好比在调用函数时,不是直接调用,而是间接调用。

7.过程式程序与OOP的区别

过程式程序创建在函数之上,数据为函数服务。面向对象编程从相反的角度来看待问题。它以程序的数据为中心,函数为数据服务。在OOP中,不在重点关注程序中得函数,而是专一与数据。

8.id

id是一种泛型,用于表示任何种类的对象。

9.OOP中得一些术语

类:类是一种结构,它表示对象的类型。对象引用类来获取和自己有关的各类信息,特别是运行什么代码来处理每种操做。

对象:对象是一种结构,它包含值和指向其类的隐藏指针。

实例:实例是“对象”的另外一种称呼。

消息:消息是对象能够执行的操做,用于通知对象去作什么。

方法:方法是为响应消息而运行的代码。根据对象的类,消息能够调用不一样的方法。

方法调度程序:是objective-c使用的一种机制,用于推测执行什么方法以响应某个特定的消息。

接口:接口是对象的类应该提供的特性的描述。接口不提供实现细节。

实现:实现是使接口正常工做的代码。

10.中缀符

objective- c有一种名为中缀符的语法技术。方法的名称及其参数都是合在一块儿的。例如: [trxtThing setStringValue:@"Hello there" color:kBlueColor]; 中 setStringValue: 和 color:其实是参数的名称(其实是方法名称的一部分)。使代码可读性更强,更容易理解参数的用途。

11.先行短线

-(void)draw;

前面的短线代表这是objective-c方法的生命。这是一种区分函数原型与方法声明的方式,函数原型中没有先行短线。-表明是实例方法。+表明是类方法。

12.@interface

建立某个特定类的对象以前,objective-c编译器须要一些有关该类的信息。他必须知道对象的数据成员和它提供的特性能够使用@interface指令把这种信息传递给编译器。用于定义类的公共接口。

13.@implementation

是一个编译器指令,代表你将为某个类提供代码。类名出如今@implementation以后。该行的结尾处没有分号。由于在objective-c编译器指令后没必要使用分号。

@interface和@implementation间的参数名不一样是正确的。

在@interface中没有声明却在@implementation中实现的方法是私有方法。

14.实例化

建立对象的过程叫作实例化。实例化对象时,须要分配内存,而后这些内存被初始化并保存一些有用的默认值,这些值不一样于你在得到新分配内存时获得的随机值。内存分配和初始化完成后,就建立了一个新的对象实例。

15.继承

建立一个新类时,一般须要定义新类以区别于其余类以及现有类。使用继承能够定义一个具备父类全部功能的新类,它继承了父类的这些功能。

objective-c没有多继承。

建立一个新类时,其对象首先从自身的超类中继承实例变量,而后添加他们本身的实例变量。

超类

父类

子类

孩子类

重写

方法调度:objective-c的方法调度程序将子当前类中搜索响应的方法。若是调度程序没法在接受消息的对象类中找到响应的方法,它就会在该类的超类中进行查找。顺着继承链找到下一个超类进行查找,直到NSObject类中也没有该方法,则会出现运行时错误。

16.复合

对象引用其余对象时,能够利用其余对象提供的特性,这就是复合。

17.UML

UML是一种用图表表示类,类的内容以及他们之间关系的常见方法。

18.多态

使用更具体种类的对象(子类对象)代替通常类型(父类),这种能力称为多态性。

19.self

是一个指向接收消息的对象的指针。指向第一个实例变量isa。由于objective-c编译器已经看到了全部这些类的@interface声明,所以,它能直到对象中实力变量的布局,经过这些重要的信息,编译器能够产生代码并查找任何须要的实例变量。

基地址加偏移:编译器使用“基地址加偏移”机制实现奇妙的功能。给定的对象基地址,是指第一个实例变量的首个字节在内存中得位置,经过在该地址加上偏移地址,编译器就能够查到其余实例变量的位置。

20.间接寻址方式,直接寻址方式

21.super

objective-c提供某种方式来重写方法,而且仍然调用超类的实现方式。当须要超类实现自身的功能,同时在前面或者后面执行某些额外的工做时,这种机制很是有用。为了调用继承方法的实现,须要使用super做为方法调用的目标。

22.cocoa

cocoa其实是由2个不一样的框架组成的:Foundation Kit和 Application Kit。Application Kit包含了全部的用户接口对象和高级类。

Foundation Kit

23.NSAutoreleasePool

mian()函数建立了(经过alloc)并初始化(经过init)了一个NSAutoreleasePool实例。在mian()函数结尾,这个池被排空。这就是Cocoa内存管理的预览。

24.NSRange

typedef struct _NSRange {

unsigned int location;

unsigned int length;

}NSRange;

这个结构体用来表示相关事务的范围,一般是字符串里的字符范围或者数组里的元素范围。

25.三种赋值方式

1.NSRange range;

range.location = 17;

range.length = 4;

2.C语言的聚合结构赋值机制

NSRange range = {17, 4};

3.Cocoa提供的一个快捷函数NSMakeRange()

NSRange range = NSMakeRange(17, 4);

使用NSMakeRange()的好处是你能够在任何可以使用函数的地方使用它,例如在方法调用中将其当成参数传递。

26.几何数据类型

1.NSPoint  表明笛卡儿平面中得一个点(x, y).

typedef struct _NSPoint {

float x;

float y;

}NSPoint;

2.NSSize  用来存储长度和宽度

typedef struct NSSize {

float width;

float height;

}NSSize;

3.NSRect 矩形数据类型,它是由点和大小复合而成

typedef struct _NSRect {

NSPoint origin;

NSSize size;

}NSRect;

27.字符串NSString

stringWithFormat:就是一个工厂方法,它根据你提供的参数建立新对象。

length:长度

isEqualToString:比较字符串内容是否相同

compart:将接受对象和传递来的字符串逐个字符的进行比较。返回一个enum数据

NSCaseInsensitiveSearch:不区分大小写字符。

NSLiteralSearch:进行彻底比较,区分大小写

NSNumericSearch:比较字符串的字符个数,而不是字符值。

-(NSRange)rangeOfString:(NSString *)aString;

返回的range.start为开始位置,range.length为长度。

28.NSMutableString可变字符串。

stringWithCapacity:建立一个新的NSMutableString

字符串的大小并不只限于所提供的容量,这个容量仅是个最优值。若是要建立一个40mb的字符串。

NSMutableString *str = [NSMutableString stringWithCapacity:42];

appendString接受参数aString,而后将其复制到接收对象的末尾。

appendFormat与stringWithFormat:相似,但它将格式化的字符串附加在接收字符串的末尾,而不是建立新的字符串对象。

29.集合家族

1.NSArray:是一个Cocoa类,用来存储对象的有序列表。

两个限制:1.只能存储objective-c的对象,不能存储C语言中得基本数据类型。

2.也不能存储nil。

30.枚举器,快速枚举

31.NSDictionary字典

关键字及其定义的集合。

32.NSNumber包装(以对象形式实现)基本数据类型

装箱:将一个基本类型的数据包装成对象。

取消装箱:从对象中提取基本类型的数据。

objective-c不支持自动装箱。

33.NSValue是NSNumber的父类。

+(NSValue *)valueWithBytes:(const void *)value objCType:(const char *)type;

传 递的参数是你想要包装的数值的地址(如一个NSSize或你本身的struct)。一般,获得的是你想要存储的变量的地址(在C语言中使用操做 符&)。你也能够提供一个用来描述这个数据类型的字符串,一般用来讲明struct中实体的类型和大小。你不用本身写代码来生成这个字符 串,@encode编译器指令能够接受数据类型的名称并为你生成合适的字符串。

NSRect rect = NSMakeRect(1, 2, 30, 40);

NSValue *value;

value = [NSValue valueWithBytes:&rect objCType:@encode(NSRect)];

[array addObject:value];

34.NSNull只有一个方法[NSNull null];

[NSNull null]老是返回同样的数值,因此你能够使用运算符==将该值与其余值进行比较。

35.单实例架构:只须要一个实例。

查找文件:

例如:NSFileManager *manager;

manager = [NSFileManager defaultManager];

defaultManager能够为咱们建立一个属于咱们本身的NSFileManger对象。

NSString *home = [@"~" stringByExpandingTildeInPath];将~替换成当前用户的主目录。

NSDirectoryEnumerator *direnum = [manager enumeratorAtPath:home]; 返回一个 NSDictionaryEnumerator,它是NSEnumerator的子类。每次在这个枚举器对象中调用nextObject时,都会返回该目 录中得一个文件的另外一个路径。

36.内存管理

1)对象生命周期

对象的生命周期包括诞生(alloc或者new方法实现),生存(接受消息和执行操做),交友(借助方法的组合和参数)以及当他们的生命结束时最终死去(被释放)。当对象的生命周期结束时,他们的原材料(内存)将被回收以供新的对象使用。

2)引用计数

cocoa 采用了一种称为引用计数的技术,有时候也叫保留计数。每一个对象有一个与之相关联的整数,称做它的引用计数器或保留计数器。当某段代码须要 访问一 个对象时,该代码将该对象的保留计数器值+1,表示“我要访问该对象”。当这段代码结束对象访问时,将对象的保留计数器值-1,表示它再也不访问该对象,当 保留计数器值为0时,表示再也不有代码访问该对象了,所以该对象被销毁,其占用的内存被系统回收以便重用。

alloc,new,copy  1

retain  +1

release  -1

3)对象全部权

若是一个对象具备指向其余对象的实力变量,则称该对象拥有这些对象。

在类A中  B对象拥有其指向的C对象,则B对象拥有C对象。

若是一个函数建立了一个对象,则称该函数拥有它建立的这个对象。

main()函数建立了对象a  称main()函数拥有a对象

当多个实体拥有某个特定的对象时,对象的全部权关系就更加复杂了,这也是保留计数器值可能大于1的缘由。

例子:

main() {

Engine *engine = [Engine new];

[car setEngine:engine];

}

现 在哪一个实体拥有engine对象?是main函数仍是car类?哪一个实体负责确保当engine对象再也不被使用时可以收到release消息?因 为 car类正在使用engine对象,因此不多是main函数。由于main函数随后还可能会使用engine对象,因此也不多是car类。

解 决方法是让car类保留engine对象,将engine对象的保留计数器值增长到2。这是由于car类和main函数这2个实体都正在使用 engine对象。car类应该在setEngine:方法中保留engine对象,而main函数应该释放engine对象。而后,当car类完成其任 务时再释放engine对象(在其dealloc方法中),最后engine对象占用的资源被回收。

若是您使用名字以“alloc”或 “new”开头或名字中包含“copy”的方法(例如alloc,newObject或mutableCopy) 建立了 一个对象,则您会得到该对象的全部权;或者若是您向一个对象发送了一条retain消息,则您也会得到该对象的全部权。

4)访问方法中得保留和释放

5)自动释放池NSAutoreleasePool

是一个存放实体的池(集合)。你能够用NSMutableArray来编写本身的自动释放池,以容纳对象并在dealloc方法中向池中得全部对象发送release消息。

autorelease

当给一个对象发送autorelease消息时,其实是将该对象添加到NSAutoreleasePool中。当自动释放池被销毁时,会向该池中得全部对象发送release消息。

6)自动释放池的销毁时间

在咱们一直使用的Foudation库工具中,建立和销毁自动释放池的方法很是明确:

NSAutoreleasePool *pool;

pool = [[NSAutoreleasePool alloc] init];

...

[pool release];

创 建一个自动释放池时,该池自动成为活动的池。释放该池时,其保留计数器值归0,而后该池被销毁。在销毁的过程当中,该池释放其包含的全部对象。当使 用 Application Kit时,cocoa按期自动为你建立和销毁自动释放池。一般是在程序处理完当前事件之后执行这些操做。你能够使用任意多得自动 释放对象,当再也不使用它们时,自动释放池将自动为你清理这些对象。

你可能已经在xcode自动生成代码中碰见过另外一种销毁自动释放池中对象的方式:-drain方法。该方法只是清空自动释放池而不是销毁它。而且只适用于mac os x10.4以上的版本。

7)自动释放池的工做过程

我 们在任什么时候候向一个对象发送autorelease消息,该对象都会呗添加到这个自动释放池中。被加入到自动释放池的对象的引用计数器值不会变 化。当自 动释放池被销毁时(向自动释放池发送release消息,自动释放池的引用计数器值变为0,调用自身的dealloc函数),会调用自身的dealloc 函数,会向池中得对象发送release消息。

37.cocoa内存管理规则

1)当你使用new,alloc或copy方法建立一个对象时,该对象的保留计数器值为1。当再也不使用该对象时,你要负责向该对象发送一条release或autorelease消息。这样,该对象将在其使用寿命结束时被销毁。

2)当你经过任何其余方法得到一个对象时,则假设该对象的保留计数器值为1,并且已经被设置为自动释放,你不须要执行任何操做来确保该对象被清理。若是你打算在一段时间内拥有该对象,则须要保留它并确保在操做完成时释放它。

3)若是你保留了某个对象,你须要(最终)释放或自动释放该对象。必须保持retain方法和release方法的使用次数相同。

38.清理自动释放池

因为自动释放池的销毁时间是彻底确立的,因此它在循环执行过程当中不会被销毁。在迭代中或者循环中,须要创建本身的自动释放池。

39.垃圾回收gc

自 动内存管理机制。objective-c的垃圾回收器是一种继承性的垃圾回收器。与那些已经存在了一段时间的对象相比,新建立的对象更可能被当成 垃圾。 垃圾回收器按期检查变量和对象以及他们之间的指针,当发现没有任何变量指向某个对象时,就将该对象视为应该被丢弃的垃圾。若是你再一个实例变量中指向某个 对象,必定要在某个时候使该实例变量赋值为nil,以取消对该对象的引用并使垃圾回收器知道该对象能够被清理了。

与自动释放池同样,垃圾回收器也是在时间循环结束时才触发。

ARC是什么?

ARC是iOS 5推出的新功能,全称叫 ARC(Automatic Reference Counting)。简单地说,就是代码中自动加入了retain/release,原先须要手动添加的用来处理内存管理的引用计数的代码能够自动地由编译器完成了。

该 机能在 iOS 5/ Mac OS X 10.7 开始导入,利用 Xcode4.2 能够使用该机能。简单地理解ARC,就是经过指定的语 法,让编 译器(LLVM 3.0)在编译代码时,自动生成实例的引用计数管理部分代码。有一点,ARC并非GC,它只是一种代码静态分析 (Static Analyzer)工具。

40.分配

是一个新对象诞生的过程。是从操做系统得到一块内存并将其指定为存放对象的实例变量的位置。

40.初始化

与分配对应的操做是初始化。初始化从操做系统取得一块内存。准备用于存储对象。

嵌套调用技术很是重要,由于初始化方法返回的对象可能与分配的对象不一样。

1)初始化时作什么?

给实例变量赋值并建立你得对象完成任务所须要的其余对象。

2)便利初始化函数

许多类包含便利初始化函数。用来完成某些额外的工做的初始化方法,能够减小你本身完成这些工做的麻烦。

例如:NSString类中-(id)initWithFormat:(NSString *)format,...;

3)指定初始化函数

类中的某个初始化方法被指派为指定初始化函数。该类全部初始化方法使用指定初始化函数执行初始化操做。子类使用其超类的指定初始化函数实现超类的初始化。

例如:其余初始化函数经过指定初始化函数实现。

41.初始化函数规则

不须要为你本身的类建立初始化函数方法。若是不须要设置任何状态,或者只须要alloc方法将内存清零的默认行为,则不须要担忧init。

若是构造了一个初始化函数,则必定要在你本身的指定初始化函数中调用超类的指定初始化函数。必定要将超类的初始化函数的值赋给self对象,并返回你本身的初始化方法的值。由于超类可能决定返回一个彻底不一样的对象。

若是初始化函数不止一个,则要选择一个座位指定初始化函数。被选定的方法应该调用超类指定初始化函数。要按照指定初始化函数的形式实现全部其余初始化函数,就像咱们在前面的实现同样。

42.特性@property

objective-c2.0的特性只适用于mac os x 10.5或更高版本。特性主要应用于cocoa的新组件(尤为是华丽夺目的core Animation效果)。

1)简化接口

@property预编译指令的做用是自动生命属性的setter和getter方法。

2)@synthesize也是一种新的编译器功能,表示“建立该属性的访问器”。

3)点表达式

若是点表达式出如今=左边,该属性名称的setter方法(set方法)将被调用。若是点表达式出如今对象变量右边,则该属性名称的getter方法(get方法)将被调用。

4)特性扩展

@property()括号里面的东西,是对应在set方法中要添加的语句。好比我在括号里写retain,就至关于在它的set方法里添加了一句 [xx retain]。

@property属性

属性分为3类:

1.读写属性(Writability)包含:readwrite / readonly

2.setter语义(Setter Semantics)包含:assign / retain / copy

3.原子性(Atomicity)包含:nonatomic

下面具体说明各个属性的含义

readwrite / readonly:

决定是否生成set访问器,readwrite是默认属性,生成getter和setter方法;readonly只生成getter方法,不生成setter方法。

readonly关键字表明setter不会被生成, 因此它不能够和 copy/retain/assign组合使用。

assign / retain / copy:

这些属性用于指定set访问器的语义,也就是说,这些属性决定了以何种方式对数据成员赋予新值。

assign:

直接赋值,索引计数不改变,适用于简单数据类型,例如:NSIngeter、CGFloat、int、char等。

retain:

指针的拷贝,使用的是原来的内存空间。

对象的索引计数加1。

此属性只能用于Objective-C对象类型,而不能用于Core Foundation对象。(缘由很明显,retain会增长对象的引用计数,而基本数据类型或者Core Foundation对象都没有引用计数)。

copy:

对象的拷贝,新申请一块内存空间,并把原始内容复制到那片空间。

新对象的索引计数为1。

此属性只对那些实行了NSCopying协议的对象类型有效。

不少Objective-C中的object最好使用用retain,一些特别的object(例如:string)使用copy。

nonatomic:

非原子性访问,不加同步,多线程并发访问会提升性能。若是不加此属性,则默认是两个访问方法都为原子型事务访问。默认值是atomic,为原子操做。

(atomic是Objc使用的一种线程保护技术,基本上来说,是防止在写未完成的时候被另一个线程读取,形成数据错误。而这种机制是耗费系统资源的, 因此在iPhone这种小型设备上,若是没有使用多线程间的通信编程,那么nonatomic是一个很是好的选择。)

5)保留周期retain cycle

引用计数器在该周期中归零。

6)什么是属性访问器

属性访问器(Property Accessor),包括 get 访问器和 set 访问器分别用于字段的读写操做

其设计目的主要是为了实现面向对象(OO)中的封装思想。根据该思想,字段最好设为private,一个精巧的类最好不要直接把字段设为公有提供给客户调用端直接访问

另外要注意属性自己并不必定和字段相联系

7)self.a与a的区别

self.a使编译器知道咱们指望使用访问器访问a。若是只使用裸名a,编译器将假设咱们直接修改了实例变量。

8)self.a = nil

这 行代码表示使用nil参数调用setName:方法。生成的访问器方法将自动释放之前的name对象,并使用nil替代a。该方法完成了释放 name对 象所占用内存的操做。固然,也能够只释放name对象以清理其占用的内存。若是你再dealloc方法之外的地方清除特性,那么使用"将nil赋值给对 象"的方法能够将特性设置为nil,同时能够使咱们避免对已释放内存的悬空引用问题。

9)特性不是万能的

有些方法不适合特性所能涵盖的方法的至关狭小的范围。特性不支持那些须要接受额外参数的方法。

43.类别@category

1)声明类别

@interface NSString (NumberConvenience)

-(NSNumber *)lengthAsNumber;

@end

该 声明具备2个特色。首先,现有类位于@interface关键字以后,其后是位于圆括号中的一个新名称。该声明表示,类别的名称是 NumberConvenience,并且该类别将向NSString类中添加方法。只要保证类别名称的惟一性,你能够向一个类中添加任意多得类别。

其次,你能够指定但愿向其添加类别的类以及类别的名称,并且你还能够列出添加的方法,最后以@end结束。因为不能添加新实现变量,所以与类声明不一样的是,类别的声明中没有实例变量部分。

2)实现类别

3)类别的局限性

第一,没法向类中添加新的实例变量。类别没有位置容纳实例变量。

第二,名称冲突,即类别中得方法与现有的方法重名。当发生名称冲突时,类别具备更高的优先级。你得类别方法将彻底取代初始方法,从而没法再使用初始方法。有些编程人员在本身的类别方法中增长一个前缀,以确保不发生名称冲突。

有一些技术能够克服类别没法增长新实例变量的局限。例如,能够使用全局字典存储对象与你想要关联的额外变量之间的映射。但此时你可能须要认真考虑一下,类别是不是完成当前任务的最佳选择。

4)类别的做用

cocoa中得类别主要用于3个目的:第一,将类的实现分散到不一样文件或者不一样框架中。第二,建立对私有方法的前向引用。第三,向对象添加非正式协议。

44.run循环是一种cocoa构造,它一直处于阻塞状态(即不执行任何处理),知道某些事件发生为止。

45.响应选择器

一个类别如何知道其委托对象是否可以处理那些发送给它的消息?

类别首先检查对象,询问其可否响应该选择器。若是该对象可以响应该选择器,

1)选择器@selector()

选择器只是一个方法名称,但它以objective-c运行时使用的特殊方式编码,以快速执行查询。你能够使用@selector()预编译指令选择器,其中方法名位于圆括号中。

46.委托  非正式协议

47.正式协议

与非正式协议同样,正式协议是一个命名的方法列表。但与非正式协议不一样的是,正式协议要求显式的采用协议。采用协议的办法是在类的@interface声明中列出协议名称。采用协议意味着你承诺实现该协议的全部方法。

1)声明协议

@protocol NSCopying

-(id)copyWithZone:(NSZone *)zone;

@end

2)采用协议

@interface Car: NSObject 

{

}

@end

3)协议和数据类型

若是一个用尖括号括起来的协议名称跟随在id以后,则编译器将知道你指望任意类型的对象,只要其遵照该协议。

4)objective-c2.0的新特性@optional @required

@optional可选择实现的方法

@required必须实现的方法

所以cocoa中得非正式协议正被带有@optional的正式协议所取代。

48.Application Kit

1)IBOutlet与IBAction

他 们实际上只是APPKit提供的#defines。IBOutlet的定义没有任何做用,所以将不会对它进行编译。IBAction定义为 void,这 意味着在AppController中声明的方法的返回类型将使void。IBOutlet和IBAction不执行任何操做,他们并非用于编译的,实 际上他们是为Interface Builder以及阅读代码的人提供的标记。经过查找IBOutlet和 IBAction,Interface Builder知道AppController对象具备两个可以链接的实例变量。

2)IBOutlet是如何工做的

当 加载nib文件时(MainMenu.nib会在应用程序启动时自动加载,能够建立你本身的nib文件并自行加载),存储在nib文件中得任何对 象都会 被从新建立。这意味着会再后台执行alloc和init方法。因此,当应用程序启动时,会分配并初始化一个AppController实例。在执行 init方法期间,全部IBOutlet实例变量都为nil。只有建立了nib文件中得全部对象(这包括窗口和文本域和按钮),全部链接才算完成。

一 旦创建了全部链接(也就是将NSTextField对象的地址添加到AppController的实例变量中),会向建立的每一个对象发送消息 awakeFromNib。一个很是常见的错误是试图在init方法中使用IBOutlet执行一些操做。因为全部实例变量都为nil,发送给他们的全部 消息不执行任何操做,因此在init中得任未尝试都会发生无提示失败。(这是Cocoa致使效率低和占用大量调试时间的一个方面)。若是你想知道为何这 些操做不起做用,能够使用NSLog输出实例变量的值,并查看他们是否都为nil。对于建立的对象和发送的awakeFromNib消息,都不存在预约义 顺序。

文件加载与保存

49.属性列表

1)自动释放对象

NSDate

NSData NSData对象是不可改变的。他们被建立后就不能改变。能够使用他们,但不能改变其中的内容。

2)编码对象    编码和解码

cocoa具有一种机制来将对象自身转换为某种格式并保存到磁盘中。对象能够将他们的实例变量和其余数据块编码为数据块,而后保存到磁盘中。之后将这些数据块读回到内存中,而且还能基于保存的数据建立新对象。这个过程称为编码和解码。或称为序列化和反序列化。

50.键/值编码   KVC

是一种间接改变对象状态的方式,其实现方法是使用字符串描述要更改的对象状态部分。

1)valueForKey与setValue:forKey:

这两种方法的工做方式相同。他们首先查找名称的setter(getter)方法,若是不存在setter(getter)方法,他们将在类中查找名为名称或_名称的实例变量。而后给它赋值(取值)。无需经过对象指针直接访问实例变量。

2)路径

键路径的深度是任意的,具体取决于对象图。

键路径不只能引用对象值,还能够引用一些运算符来进行一些运算,例如获取一组值的平均值或返回这组值中得最小值和最大值。

例如:NSNumber *count;

count = [garage valueForKeyPath:@"cars.@count"];

NSLog(@"We have %@ cars", count);

咱们将路径“cars.@count”拆开,cars用于获取cars属性,它是来自garage的NSArray类型的值。接下来的部分是@count ,其中@符号意味着后面将进行一些运算。

和 cars@sun.mileage

最大值 cars@min.mileage

最小值 cars@max.mileage

3)总体操做

KVC很是棒的一点是,若是向NSArray请求一个键值,它实际上会查询数组中得每一个对象来查找这个键值,而后将查询结果打包到另外一个数组中并返回给你。这种方法也适用于经过键路径访问的对象内部的数组。

4)批处理

KVC包含两个调用,能够使用他们对对象进行批量更改。第一个调用是dictionaryWith-ValuesForKeys:。它接受一个字符串数组。该调用获取一些键,对每一个键使用valueForKey:,而后为键字符串和刚才获取的值构建一个字典。

一、Object-C有多继承吗?没有的话用什么代替?cocoa 中全部的类都是NSObject 的子类

多继承在这里是用protocol 委托代理 来实现的

你不用去考虑繁琐的多继承 ,虚基类的概念.

ood的多态特性 在 obj-c 中经过委托来实现.

二、Object-C有私有方法吗?私有变量呢?

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

@interface Controller : NSObject { NSString *something; }

+ (void)thisIsAStaticMethod;

– (void)thisIsAnInstanceMethod;

@end

@interface Controller (private) -

(void)thisIsAPrivateMethod;

@end

@private能够用来修饰私有变量

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

三、关键字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 类型,以使得其返回值不为“左值”。

四、关键字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 成员变量。

六、#import和#include的区别,@class表明什么?

@class通常用于头文件中须要声明该类的某个实例变量的时候用到,在m文件中仍是须要使用#import

而#import比起#include的好处就是不会引发重复包含

七、线程和进程的区别?

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

进 程和线程的主要差异在于它们是不一样的操做系统资源管理方式。进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程 只是一 个进程中的不一样执行路径。线程有本身的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,因此多进程的程序要比多线程的程 序健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行而且又要共享某些变量的并发操做,只能用线程,不能用进程。

八、堆和栈的区别?

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

申请大小:

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

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

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

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

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

九、Object-C的内存管理?

1.当你使用new,alloc和copy方法建立一个对象时,该对象的保留计数器值为1.当你再也不使用该对象时,你要负责向该对象发送一条release或autorelease消息.这样,该对象将在使用寿命结束时被销毁.

2.当你经过任何其余方法得到一个对象时,则假设该对象的保留计数器值为1,并且已经被设置为自动释放,你不须要执行任何操做来确保该对象被清理.若是你打算在一段时间内拥有该对象,则须要保留它并确保在操做完成时释放它.

3.若是你保留了某个对象,你须要(最终)释放或自动释放该对象.必须保持retain方法和release方法的使用次数相等.

十、为何不少内置的类,如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模式时,也要注意这点。

十一、定义属性时,什么状况使用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];

}

十二、对象是何时被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

1三、iOS有没有垃圾回收?

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

1四、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就能够正常重用了。

1五、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仍是继续作它该作的事情

1六、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中释放这些引用。

1七、列举Cocoa中常见的集中多线程的实现,并谈谈多线程安全的几种解决办法,通常什么地方会用到多线程?

NSThread,GCD等。尽可能用上层分装好的方法去实现多线程而不是手动调用NSThread。

1八、怎么理解MVC,在Cocoa中MVC是怎么实现的?

Model: 表明你的应用程序是什么(不是怎么展示)

Controller: 控制你的Model怎么展示给用户(UI逻辑)

View: Controller的奴隶。。。

1 Model,Controller,View相互通信的规则:

Controller能够直接和Model通讯

Controller也能够直接和View通讯

Model和View永远不能直接通讯

iOS中View和Controller的通讯是透明和固定的,主要经过outlet和action实现

View使用Delegate接口和Controller同步信息

View不直接和数据通讯,使用dataSource接口从Controller处获取数据

View的delegate和dataSource通常就是Controller

Controller负责为View翻译和格式化Model的数据

Model使用Notification & KVO的方式分发数据更新信息,Controller能够有选择的监听本身感兴趣的信息。

View也能够监听广播信息,但通常不是Model发出的信息

一个完整的App就是不少MVC的集合

1九、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什么区别?

2一、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) (id, SEL, …)。这样说来, IMP是一个指向函数的指针,这个被指向的函数包括id(“self”指针),调用的SEL(方法名),再加上一些其余参数.说白了IMP就是实现方法。

2二、内存管理 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的)

2三、类别的做用?

有时咱们须要在一个已经定义好的类中增长一些方法,而不想去重写该类。好比,当工程已经很大,代码量比较多,或者类中已经包住不少方法,已经有其余代码调用了该类建立对象并使用该类的方法时,能够使用类别对该类扩充新的方法。

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

2四、委托(举例)

委托代理(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之间能够经过委托来传值!

2五、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过去了

此份面试题包含40个题目,是如今网上能搜索到的一个比较热的一份,可是答案并非很详细和完整,基本答案来着cocoaChina,和一些本身的补充。

34.Difference between shallow copy and deep copy?

浅复制和深复制的区别?

答案:浅层复制:只复制指向对象的指针,而不复制引用对象自己。

深层复制:复制引用对象自己。

意思就是说我有个A对象,复制一份后获得A_copy对象后,对于浅复制来讲,A和A_copy指向的是同一个内存资源,复制的只不过是是一个指针,对象自己资源

仍是只有一份,那若是咱们对A_copy执行了修改操做,那么发现A引用的对象一样被修改,这其实违背了咱们复制拷贝的一个思想。深复制就好理解了,内存中存在了

两份独立对象自己。

用网上一哥们通俗的话将就是:

浅复制比如你和你的影子,你完蛋,你的影子也完蛋

深复制比如你和你的克隆人,你完蛋,你的克隆人还活着。

35.What is advantage of categories? What is difference between implementing a category and inheritance?

类别的做用?继承和类别在实现中有何区别?

答案:category 能够在不获悉,不改变原来代码的状况下往里面添加新的方法,只能添加,不能删除修改。

而且若是类别和原来类中的方法产生名称冲突,则类别将覆盖原来的方法,由于类别具备更高的优先级。

类别主要有3个做用:

(1)将类的实现分散到多个不一样文件或多个不一样框架中。

(2)建立对私有方法的前向引用。

(3)向对象添加非正式协议。

继承能够增长,修改或者删除方法,而且能够增长属性。

36.Difference between categories and extensions?

类别和类扩展的区别。

答案:category和extensions的不一样在于后者能够添加属性。另外后者添加的方法是必需要实现的。

extensions能够认为是一个私有的Category。

37.Difference between protocol in objective c and interfaces in java?

oc中的协议和java中的接口概念有何不一样?

答案:OC中的代理有2层含义,官方定义为 formal和informal protocol。前者和Java接口同样。

informal protocol中的方法属于设计模式考虑范畴,不是必须实现的,可是若是有实现,就会改变类的属性。

其实关于正式协议,类别和非正式协议我很早前学习的时候大体看过,也写在了学习教程里

“非正式协议概念其实就是类别的另外一种表达方式“这里有一些你可能但愿实现的方法,你能够使用他们更好的完成工做”。

这个意思是,这些是可选的。好比我门要一个更好的方法,咱们就会申明一个这样的类别去实现。而后你在后期能够直接使用这些更好的方法。

这么看,总以为类别这玩意儿有点像协议的可选协议。"

如今来看,其实protocal已经开始对二者都统一和规范起来操做,由于资料中说“非正式协议使用interface修饰“,

如今咱们看到协议中两个修饰词:“必须实现(@requied)”和“可选实现(@optional)”。

38.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

{

([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查找的逻辑理解,就说的过去了。

39.What is purpose of delegates?

代理的做用?

答案:代理的目的是改变或传递控制链。容许一个类在某些特定时刻通知到其余类,而不须要获取到那些类的指针。能够减小框架复杂度。

另一点,代理能够理解为java中的回调监听机制的一种相似。

40.What are mutable and immutable types in Objective C?

oc中可修改和不能够修改类型。

答案:可修改不可修改的集合类。这个我我的简单理解就是可动态添加修改和不可动态添加修改同样。

好比NSArray和NSMutableArray。前者在初始化后的内存控件就是固定不可变的,后者能够添加等,能够动态申请新的内存空间。

41.When we call objective c is runtime language what does it mean?

咱们说的oc是动态运行时语言是什么意思?

答案:多态。 主要是将数据类型的肯定由编译时,推迟到了运行时。

这个问题其实浅涉及到两个概念,运行时和多态。

简单来讲,运行时机制使咱们直到运行时才去决定一个对象的类别,以及调用该类别对象指定方法。

多态:不一样对象以本身的方式响应相同的消息的能力叫作多态。意思就是假设生物类(life)都用有一个相同的方法-eat;

那人类属于生物,猪也属于生物,都继承了life后,实现各自的eat,可是调用是咱们只需调用各自的eat方法。

也就是不一样的对象以本身的方式响应了相同的消息(响应了eat这个选择器)。

所以也能够说,运行时机制是多态的基础?~~~

42.what is difference between NSNotification and protocol?

通知和协议的不一样之处?

答案:协议有控制链(has-a)的关系,通知没有。

首先我一开始也不太明白,什么叫控制链(专业术语了~)。可是简单分析下通知和代理的行为模式,咱们大体能够有本身的理解

简单来讲,通知的话,它能够一对多,一条消息能够发送给多个消息接受者。

代理按咱们的理解,到不是直接说不能一对多,好比咱们知道的明星经济代理人,不少时候一个经济人负责好几个明星的事务。

只是对于不一样明星间,代理的事物对象都是不同的,一一对应,不可能说明天要处理A明星要一个发布会,代理人发出处理发布会的消息后,别称B的

发布会了。可是通知就不同,他只关心发出通知,而不关心多少接收到感兴趣要处理。

所以控制链(has-a从英语单词大体能够看出,单一拥有和可控制的对应关系。

43.What is push notification?

什么是推送消息?

答案:太简单,不做答~~~~~~~~~~

这是cocoa上的答案。

其实到不是说太简单,只是太泛泛的一个概念的东西。就比如说,什么是人。

推送通知更是一种技术。

简单点就是客户端获取资源的一种手段。

普通状况下,都是客户端主动的pull。

推送则是服务器端主动push。

44.Polymorphism?

关于多态性

答案:多态,子类指针能够赋值给父类。

这个题目其实能够出到一切面向对象语言中,

所以关于多态,继承和封装基本最好都有个自我意识的理解,也并不是必定要把书上资料上写的能背出来。

最重要的是转化成自我理解。

45.Singleton?

对于单例的理解

答案:11,12题目其实出的有点泛泛的感受了,可能说是编程语言须要或是必备的基础。

基本能用熟悉的语言写出一个单例,以及能够运用到的场景或是你编程中碰到过运用的此种模式的框架类等。

进一步点,考虑下如何在多线程访问单例时的安全性。

46.What is responder chain?

说说响应链

答案: 事件响应链。包括点击事件,画面刷新事件等。在视图栈内从上至下,或者从下之上传播。

能够说点事件的分发,传递以及处理。具体能够去看下touch事件这块。由于问的太抽象化了

严重怀疑题目出到越后面就越笼统。

47.Difference between frame and bounds?

frame和bounds有什么不一样?

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

bounds指的是:该view在自己坐标系统中 的位置和大小。(参照点是自己坐标系统)

48.Difference between method and selector?

方法和选择器有何不一样?

答案:selector是一个方法的名字,method是一个组合体,包含了名字和实现.

详情能够看apple文档。

49.Is there any garbage collection mechanism in Objective C.?

OC的垃圾回收机制?

答案: OC2.0有Garbage collection,可是iOS平台不提供。

通常咱们了解的objective-c对于内存管理都是手动操做的,可是也有自动释放池。

可是差了大部分资料,貌似不要和arc机制搞混就行了。

求更多~~

50.NSOperation queue?

答案:存放NSOperation的集合类。

操做和操做队列,基本能够当作java中的线程和线程池的概念。用于处理ios多线程开发的问题。

网上部分资料提到一点是,虽然是queue,可是却并非带有队列的概念,放入的操做并不是是按照严格的先进现出。

这边又有个疑点是,对于队列来讲,先进先出的概念是Afunc添加进队列,Bfunc紧跟着也进入队列,Afunc先执行这个是必然的,

可是Bfunc是等Afunc彻底操做完之后,B才开始启动而且执行,所以队列的概念离乱上有点违背了多线程处理这个概念。

可是转念一想其实能够参考银行的取票和叫号系统。

所以对于A比B先排队取票可是B率先执行完操做,咱们亦然能够感性认为这仍是一个队列。

可是后来看到一票关于这操做队列话题的文章,其中有一句提到

“由于两个操做提交的时间间隔很近,线程池中的线程,谁先启动是不定的。”

瞬间以为这个queue名字有点忽悠人了,还不如pool~

综合一点,咱们知道他能够比较大的用处在于能够帮组多线程编程就行了。

51.What is lazy loading?

答案:懒汉模式,只在用到的时候才去初始化。

也能够理解成延时加载。

我以为最好也最简单的一个列子就是tableView中图片的加载显示了。

一个延时载,避免内存太高,一个异步加载,避免线程堵塞。

52.Can we use two tableview controllers on one viewcontroller?

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

答案:一个视图控制只提供了一个View视图,理论上一个tableViewController也不能放吧,

只能说能够嵌入一个tableview视图。固然,题目自己也有歧义,若是不是咱们定性思惟认为的UIViewController,

而是宏观的表示视图控制者,那咱们却是能够把其当作一个视图控制者,它能够控制多个视图控制器,好比TabbarController

那样的感受。

53.Can we use one tableview with two different datasources? How you will achieve this?

一个tableView是否能够关联两个不一样的数据源?你会怎么处理?

答案:首先咱们从代码来看,数据源如何关联上的,实际上是在数据源关联的代理方法里实现的。

所以咱们并不关心如何去关联他,他怎么关联上,方法只是让我返回根据本身的须要去设置如相关的数据源。

 

所以,我以为能够设置多个数据源啊,可是有个问题是,你这是想干吗呢?想让列表如何显示,不一样的数据源分区块显示?

 
 
 
 

ios面试攻略(1.1)  

2013-10-22 20:27:37|  分类: IOS面试 |  标签:ios  面试  |举报|字号 订阅

 
 
 
 
1.Object-c的类能够多重继承么?能够实现多个接口么??
没有,protocol  代替,Object-c的类不能够多重继承。
2.#import 跟#include 又什么区别,@class呢; #import<> 跟 #import”"又什么区别?? 
#import 能防止重复引用,#include 不能,@class 前置声明一个类。
3.属性readwrite,readonly,assign,retain,copy,nonatomic 各是什么做用,在那种状况下用 ?
四、为何不少内置的类,如TableViewController的delegate的属性是assign不是retain?
防止循环引用。
五、定义属性时,什么状况使用copy、assign、retain??
copy:拷贝对象。assign:传值,通常用于基础类型。retain:传地址,引用计数器加一。
6,委托是什么?委托的property声明用什么属性?为何?
代理的目的是改变或传递控制链,容许一个类在某些特定时刻通知到其余类而不须要获取那些类的指针。
7,类别的做用?
1),将类的实现分散到多个类中2),建立对私有方法的引用3),能够添加或修改方法,属性
8,.id 声明的对象有什么特性??
能够是任意类型的对象,是个很重要的类型,是个能够指向任何类型的指针或者能够理解为指向任何未知类型的指针。
9,.MVC是什么?有什么特性?为何在iPhone上被普遍运用?
MVC设计模式是三种对象:模型对象,视图对象和控制器对象。模型对象表明应用程序的数据和定义操做数据的逻辑。视图对象显示应用程序的模型数据。控制器对象是协调视图和模型对象。
10,对于语句NSString* testObject = [[NSData alloc] init];testObject 在编译时和运行时分别是什么类型的对象?
11.什么是安全释放?
12,为何有些4.0独有的objective-c 函数在3.1上运行时会报错.而4.0独有的类在3.1上分配内存时不会报错?分配的结果是什么?
13,为何4.0独有的c函数在3.1的机器上运行不会报错(在没有调用的状况下?)而4.0独有的类名在3.1的机器上一运行就报错?
?14,常见的object-c的数据类型有那些, 和 c 的 基本数据类型有什么区别?如:nsinteger 和int
15,.property中属性retain,copy,assgin的含义分别是什么?有什么区别?将其转换成get/set方法怎么作?有什么注意事项?
1六、什么是Notification? 
Notification是一种消息,它传递给一个或多个观察对象用来通知它们程序里发生了一个事件。
1七、何时用delegate,何时用Notification?
当处理单个须要在另外类触发当前类行为的事件时用代理,多个事件用 Notification.
1八、线程理解,有什么好处?
线程建立和启动,NSThread  detachNew建立和NSThread 建立两中方式
线程共享同一应用程序的部份内存空间它们拥有对数据相同的访问权限
19.线程和进程的区别和联系?
线程和进程都是程序运行的基本单元,区别在于进程在运行中拥有独立的内存单元,而多个线程共享内存,提升程序效率,线程不能独立执行。
20,线程是什么? 有哪些注意事项.?
21,.notification是同步仍是异步? kvo是同步仍是异步?notification是全进程空间的通知吗?
22.浅拷贝和深拷贝区别是什么?…
浅复制:只复制指向对象的指针,而不复制引用对象自己。深复制:复制引用对象自己。
23,.NSString 和 NSMutableString 有什么区别?
24.for(int index = 0; index < 20; index ++){?    NSString *tempStr = @”tempStr”;?    NSLog(tempStr);?    NSNumber *tempNumber = [NSNumber numberWithInt:2];?    NSLog(tempNumber);?}?这段代码有什么问题.?会不会形成内存泄露(多线程)?在内存紧张的设备上作大循环时自动释放池是写在循环内好仍是循环外好?为何?
25,.内存管理的几条原则时什么?按照默认法则.那些关键字生成的对象须要手动释放?在和property结合的时候怎样有效的避免内存泄露?
26,.在一个对象释放前.若是他被加到了notificationCenter 中.不在notificationcenter中remove这个对象可能会出现什么问题?
27,.怎样实现一个 singleton的类.给出思路。
单例是在程序生命周期里只被实例化过一次的 类
28.什么是序列化或者Acrchiving,能够用来作什么,怎样与copy结合,原理是什么?.
29.在iphone上有两件事情要作,请问是在一个线程里按顺序作效率高仍是两个线程里作效率高?为何?
30,.runloop是什么?在主线程中的某个函数里调用了异步函数,怎么样block当前线程,且还能响应当前线程的timer事件,touch事件等.
31,ios平台怎么作数据的持久化?coredata和sqlite有无必然联系?coredata是一个关系型数据库吗?
32.阐述一个nil对象从interface bulider产生,到载入程序运行空间,最后被释放时所经历的生命周期.
33,响应者链是什么?
34,.timer的间隔周期准吗?为何?怎样实现一个精准的timer?
35.UIscrollVew用到了什么设计模式?还能再foundation库中找到相似的吗?
36.C和obj-c 如何混用?
37,ViewController 的 loadView, viewDidLoad, viewDidUnload 分别是在何时调用的?
view为空时调用loadView,加载完成时调用viewDidLoad,释放时调用viewDidUnload.
38.ViewController 的 didReceiveMemoryWarning 是在何时被调用的?
39.谈谈你对ARC 的认识和理解?
代码中自动加入了retain/release,原先须要手动添加的用来处理内存管理的引用计数的代码能够自动地由编译器完成了,代码高速化,因为使用编译器管理引用计数,减小了低效代码的可能性
40, Object-C有私有方法吗?私有变量呢??没,有。
4一、Object-C的内存管理??引用计数器。??
4二、对象是何时被release的??引用计数器为0.
4三、iOS有没有垃圾回收??没。
4四、tableView的重用机制??复用标记。
4五、ViewController 的loadView、viewDidLoad、viewDidUnload分别是何时调用的,在自定义ViewController时在这几个函数中应该作什么工做??当view为nil时调用loadView,view完成加载调用viewDidLoad,view释放时调用viewDidUnload.?
4六、ViewController的didReceiveMemoryWarning是在何时调用的?默认的操做是什么??内存超过阙值,尝试释放view.
4七、列举Cocoa中常见的几种多线程的实现,并谈谈多线程安全的几种解决办法,通常什么地方会用到多线程??NSThread,GCD等。尽可能用上层分装好的方法去实现多线程而不是手动调用NSThread。
4八、self.跟self什么区别?
self.表示对象的属性,self表示对象自己
4九、id、nil表明什么??id至关于void*,nil是空对象。
50、ObjC中,与alloc语义相反的方法是dealloc仍是release?与retain语义相反的方法是dealloc仍是release,为何?须要与alloc配对使用的方法是dealloc仍是release,为何??
5一、autorelease的对象是在何时被release的?
自动释放池中全部对象释放完后释放。
5二、这段代码有什么问题,如何修改?for (int i = 0; i < someLargeNumber; i++) { ?NSString *string = @”Abc”;?string = [string lowercaseString];?string = [string stringByAppendingString:@"xyz"];?NSLog(@“%@”, string);?} ?5三、autorelease和垃圾回收机制(gc)有什么关系? 
内存释放池提供了一个对象容器,每次对象发送autorelease消息时,对象的引用计数并不真正变化,而是向内存释放池中添加一条记录,记下对象的这 种要求。直到当内存释放池发送drain或release消息时,即当池被销毁前会通知池中的全部对象,所有发送release消息才会真正将引用计数减 少?。?
5四、考察对@interface与@propety的理解
只用 @ interface声明的变量只能在当前的类中访问,在其余类没法访问,而@ propety声明的变量能够在外部访问。@ propety声明的变量能够打点调用
5五、objective-c中的类型转换分为哪几类
字符串拼接,强制类型转换
5六、多态的理解
Object-C是面向对象的编程语言,它具备面向对象编程的一些特性,封装性,继承性和多态性。不一样对象以本身的方式响应相同的消息的能力叫多态。多态的主要好处就是简化了编程接口,
 

腾讯面试题
1。简述push原理,push的证书和其它的右什么不同?
2。viewcontroller的一些方法的说明viewDidLoad, viewWillDisappear, viewWillAppear方法的 顺序和 做用?
3。frame 和 bounds 的 区别 ,bound的大小改变frame 改变吗?
4。sqlite中插入特殊字符的方法和接收处处理方法。
5。谈谈你对数组和链表认识,还有你是怎么用他们的?
6。冒泡算法。
7。socket编程简述
8。asihttp代码原理 ,异步请求的原理,异步请求最大数目,为何只能这么多?
9。http请求方式?
10。uiview的圆角属性设置方法。
(m_mainImgView.layer.cornerRadius = 6;
m_mainImgView.layer.masksToBounds = YES;)
11。 masksToBounds属性的做用。(决定子layer是否被当前layer的边界剪切。默认是NO。)
 
 
 
 
阅读(203)评论(0)
 

来自网络

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

 

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

void Func ( char str[100] )

 { sizeof( str ) = ? }

 void *p = malloc( 100 );

 sizeof ( p ) = ?

答:4,4

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

 

3.仍是考指针,不过我对cocoa的代码仍是不太熟悉

大概是这样的

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

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

 return ;}

-main(void)

{ NSString *a=@"Main";

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

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

 

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

 

4.用预处理指令#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会做三次++自增操做。

 

5.写一个委托的interface

@protocol MyDelegate;

@interface MyClass: NSObject

{    id <MyDelegate> delegate; }

//委托方法

@protocol MyDelegate

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

@end

6.写一个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);

 }

 

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

cocoa中全部的类都是NSObject的子类

多继承在这里是用protocol委托代理来实现的

你不用去考虑繁琐的多继承,虚基类的概念.

 ood的多态特性  在obj-c中经过委托来实现.

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

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

@interface Controller : NSObject { NSString *something; }

+ (void)thisIsAStaticMethod;

- (void)thisIsAnInstanceMethod;

@end

@interface Controller (private) -

(void)thisIsAPrivateMethod;

@end

@private能够用来修饰私有变量

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

 

9.关键字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的指针时。 

 

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” 的做用

 是防止该头文件被重复引用。

 
 
 

ios面试攻略(2.1)  

2013-10-24 15:53:54|  分类: IOS面试 |  标签:ios面试题目  |举报|字号 订阅

 
 

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

 @class通常用于头文件中须要声明该类的某个实例变量的时候用到,在m文件中仍是须要使用#import

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

12.MVC模式的理解

MVC设计模式考虑三种对象:模型对象、视图对象、和控制器对象。模型对象表明特别的知识和专业技能,它们负责保有应用程序的数据和定义操做数据的逻辑。视图对象知道如何显示应用程序的模型数据,并且可能容许用户对其进行编辑。控制器对象是应用程序的视图对象和模型对象之间的协调者。

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

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

程和线程的主要差异在于它们是不一样的操做系统资源管理方式。进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不一样执行路径。线程有本身的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,因此多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行而且又要共享某些变量的并发操做,只能用线程,不能用进程。

Add

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

简而言之,一个程序至少有一个进程,一个进程至少有一个线程.

线程的划分尺度小于进程,使得多线程程序的并发性高。

另外,进程在执行过程当中拥有独立的内存单元,而多个线程共享内存,从而极大地提升了程序的运行效率。

线程在执行过程当中与进程仍是有区别的。每一个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。可是线程不可以独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。

从逻辑角度来看,多线程的意义在于一个应用程序中,有多个执行部分能够同时执行。但操做系统并无将多个线程看作多个独立的应用,来实现进程的调度和管理以及资源分配。这就是进程和线程的重要区别。

进程是具备必定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位.

线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程本身基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),可是它可与同属一个进程的其余的线程共享进程所拥有的所有资源.

一个线程能够建立和撤销另外一个线程;同一个进程中的多个线程之间能够并发执行.

///

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

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

 进程之间通讯的途径

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

 进程死锁的缘由

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

 死锁的4个必要条件

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

 死锁的处理

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

15.堆和栈的区别

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

申请大小:

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

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

 

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

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

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

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

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

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

For example, the key path address.streetwould get the value of the address property from the receiving

object, and then determine the street property relative to the address object.

 

17.cobj-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.

 

18.目标-动做机制

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

 的形式保有其动做消息的目标。

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

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

 

19.cocoa touch框架

iPhoneOS应用程序的基础 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

网络/li>

Bonjour

WebKit

BSD Sockets

用户应用

Address Book

Core Location

Map Kit

Store Kit

 

20.objc的内存管理

 若是您经过分配和初始化(好比[[MyClass alloc] init])的方式来建立对象,您就拥有这个对象,须要负责该对象的释放。这个规则在使用NSObject的便利方法new 时也一样适用。

若是您拷贝一个对象,您也拥有拷贝获得的对象,须要负责该对象的释放。

若是您保持一个对象,您就部分拥有这个对象,须要在再也不使用时释放该对象。反过来,

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

 

21.自动释放池是什么,如何工做

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

 

1.  ojc-c是经过一种"referring counting"(引用计数)的方式来管理内存的, 对象在开始分配内存(alloc)的时候引用计数为一,之后每当碰到有copy,retain的时候引用计数都会加一, 每当碰到release和autorelease的时候引用计数就会减一,若是此对象的计数变为了0, 就会被系统销毁.

 2. NSAutoreleasePool 就是用来作引用计数的管理工做的,这个东西通常不用你管的.

 3. autorelease和release没什么区别,只是引用计数减一的时机不一样而已,autorelease会在对象的使用真正结束的时候才作引用计数减一.

 

22.类工厂方法是什么

类工厂方法的实现是为了向客户提供方便,它们将分配和初始化合在一个步骤中,返回被建立的对象,并进行自动释放处理。这些方法的形式是+ (type)className...(其中 className不包括任何前缀)。工厂方法可能不只仅为了方便使用。它们不但能够将分配和初始化合在一块儿,还能够为初始化过程提供对象的分配信息。类工厂方法的另外一个目的是使类(好比NSWorkspace)提供单件实例。虽然init...方法能够确认一 个类在每次程序运行过程只存在一个实例,但它须要首先分配一个“生的”实例,而后还必须释放该实例。工厂方法则能够避免为可能没有用的对象盲目分配内存。

 

23.单件实例是什么

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

 

24.动态绑定

—在运行时肯定要调用的方法

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

 

25.obj-c的优缺点

objc优势:

   1) Cateogies

   2) Posing

   3) 动态识别

   4) 指标计算

   5)弹性讯息传递

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

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

 缺点:

   1) 不支援命名空间

   2)  不支持运算符重载

  3) 不支持多重继承

  4) 使用动态运行时类型,全部的方法都是函数调用,因此不少编译时优化方法都用不到。(如内联函数等),性能低劣。

 

26.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格式化的函数的长度不可控,有可能格式化后的字符串会超出缓冲区的大小,形成溢出。

 

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

a)一个整型数(An integer) 

 b)一个指向整型数的指针( A pointer to an integer) 

 c)一个指向指针的的指针,它指向的指针是指向一个整型数( A pointer to a pointer to an intege)

 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

 

 

 

ios面试攻略(3.0)  

2013-10-26 21:02:14|  分类: IOS面试 |  标签:ios面试题  |举报|字号 订阅

 
 

来自:蓝色维度

1、属性相关

1.在一个对象的方法里面: self.name = “object”; 和 name =”object” 有什么不一样吗?
答:self.name = “object”会调用对象的setName()方法,name = “object”会直接把object赋值给当前对象的name属性。
2.这段代码有什么问题吗:
@implementation Person
- (void)setAge:(int)newAge {

self.age = newAge;
}
答:在进行age属性进行.的赋值时,会调用此方法的setAge方法,这样会进入无休止的循环调用中致使crash.
3.定义属性时,什么状况使用copy,assign,和retain?
答:readwrite 是可读可写特性;须要生成getter方法和setter方法时
readonly 是只读特性 只会生成getter方法 不会生成setter方法 ;不但愿属性在类外改变
assign 是赋值特性setter方法将传入参数赋值给实例变量;仅设置变量时;
retain 表示持有特性setter方法将传入参数先保留,再赋值,传入参数的retain count会+1;
copy 表示赋值特性setter方法将传入对象复制一份;须要彻底复制一份新的变量时。
// more
nonatomic 非原子操做,决定编译器生成的setter getter是不是原子操做,atomic表示多线程安全,通常使用nonatomic
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];
}

4.写一个setter方法用于完成@property (nonatomic,retain)NSString *name,
写一个setter方法用于完成@property(nonatomic,copy)NSString *name
答:// 这里主要是注意顺序,先要reain传入参数,再release原来的属性。防止name和str是同一个变量时发生错误。
// retain
- (void) setName : (NSString*) str {
[str retain];
[name release];
name = str;
}
// copy
- (void)setName:(NSString *)str
{
id t = [str copy];
[name release];
name = t;
}

5.为何不少内置类如UITableViewController的delegate属性都是assign而不是retain的?
答:会引发循环引用,致使内存没法释放

 

2、UIViewController

1.ViewController 的 loadView, viewDidLoad, viewDidUnload 分别是在何时调用的?
在自定义ViewController的时候这几个函数里面应该作什么工做?
答:当ViewControll被初始化后,调用self.view属性时,若是view为nil的话,会调用loadView方法。loadView方法调用完成后,会调用viewDidLoad。
ViewController收到内存不足的警告时,6.0如下版本会调用viewDidUnload方法。
这三个方法,在调用时,首先应该调用super类的同名方法,不然有可能引发循环调用crash。
loadView通常用于使用xib文件的状况,咱们能够不重写这个方法。
viewDidLoad里能够加载一些咱们本身的view。
viewDidUnload里实现将retain 的view release,若是是retain的IBOutlet view 属性则不要在这里release,IBOutlet会负责release 。
loadView和viewDidLoad里面加载的内容和viewDidUnload里面卸载的内容应该对应,不然容易内存泄露或者过分释放。

2.ViewController 的 didReceiveMemoryWarning 是在何时被调用的?默认的操做是什么?
答:当ViewController收到内存不足的警告时,6.0如下版本会调用viewDidUnload方法。
默认操做是调用super的同名方法,将viewController的view的全部subView移除,将view自己释放。

  

3、C语言相关

1.sizeof与strlen的区别和联系?
答:二者的联系是,均可以返回一个长度。
sizeof返回的是变量或类型所占的字节数。strlen返回的是字符串的长度。
sizeof是关键字,strlen是库函数。

2. 下列两行代码有什么区别?
char a[] = “string”;
char *b = “string”;
a是字符数组,b一个字符串,二者sizeof取值不一样。

3. 下列代码会输出什么?
#define SQ(x) (x*x)
int main()
{
int b = 3;
int a = SQ(b + 2);
printf(“%d”, a);
return 0;
}

=b+2*b+2

11,不是25.主是要宏的直接替换问题。定义宏的时候元素上要加小括号.

4. 下列代码有什么问题?
char *foo(int n)
{
char buf[32];
buf[0] = (n != 0) ? ‘T’ : ‘F’;
buf[1] = 0;
return buf;
}
返回的是野指针。

5. 下列代码有什么问题?如有错误请改正。
void swap(int *p1, int *p2)
{
int *p = p1;
p1 = p2;
p2 = p;
}
没法实现交换两个指针,参数应该用指针的指针。

6. 若 char *p = malloc(32); 则 sizeof(p) 的值是什么?
32位机器上是4

7. 用递归方式和非递归方式写函数将一个字符串按字节反转,函数原型以下:
char *reverse(char *str);
非递归:
char *reverse(char *str)
{
if (str == NULL || strlen(str) <= 1) {
return str;
}
int len = strlen(str);
char* b = (char*)malloc(len+1);// 外部去释放
strcpy(b, str);
for (int i=0; i
 char x = b[i];
b[i] = b[len-i-1];
b[len-i-1] = x;
}

return b;
}

递归:
char *reverse(char *str)
{
if (str == NULL || strlen(str) <= 1) {
return str;
}

int len = strlen(str);

char e[] = {str[len-1],0};
char s[] = {str[0],0};

char* b = (char*)malloc(len-1);
strncpy(b, str+1,len-2);

char* c = (char*)malloc(len+1);// 外部去释放,递归时可能有泄露
strcat(c, e);
strcat(c, reverse(b));
strcat(c, s);

free(b);
return c;
}

8. 为何在析构函数中不该该抛出异常?
由于析构函数主要是已经进入清理内存的阶段,这时抛出异常的话没有地方去捕捉,会引发系统异常退出。

9.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格式化的函数的长度不可控,有可能格式化后的字符串会超出缓冲区的大小,形成溢出。

10 程序在内存中运行时,内存分几个区?各自用途?
答:栈区 由编译器自动分配释放存放函数的参数值,局部变量的值等。在高级语言中不须要显式的分配和释放
堆区 通常由程序员手动分配释放,若是不释放可有由OS释放。
数据区 存储全局和静态变量。初始化的全局和静态变量在一块区域,未初始化的放在相邻的一块区域,程序结束后由系统释放。
代码区 存放函数体的二进制代码。

11 引用与指针有什么区别?
答:引用是给变量起一个别名 也就是一个变量有两个名字 他们是同一块空间
指针是分配一块内存用来保存变量的地址 间接引用变量

 

ios面试攻略(3.1)  

2013-10-27 11:18:15|  分类: IOS面试 |  标签:ios面试题目  |举报|字号 订阅

 
 
来自: 蓝色维度
4、OC相关

1.obj-c有多重继承么?不是的话有什么替代方法? Category是什么?重写一个类的方式用继承好仍是分类好?为何?
cocoa 中全部的类都是NSObject 的子类。oc不支持多继承,你不用去考虑繁琐的多继承 ,虚基类的概念.
多继承在这里是用protocol 委托代理 来实现的
Category是类别,重写一个类的方法,用继承仍是分类要根据具体状况分析。

分类与继承:
通常状况用分类好,用Category去重写类的方法,仅对本Category有效,不会影响到其余类与原有类的关系。可是若是须要在重写的时候,还要调用原来的方法,就须要用继承了。分类是彻底重写,没法调用原来的同名方法。

2.obj-c有私有方法么?私有变量呢 ?
objective-c – 类里面的方法只有两种, 静态方法和实例方法.
可是能够经过把方法的声明和定义都放在.m文件中来实现一个表面上的私有方法。
有私有变量,能够经过@private来修饰,或者把声明放到.m文件中。
Objective‐C中,全部实例变量默认都是私有的,全部实例方法默认都是公有的

3.#import跟#include的区别? 后面的括号<>与”" 的区别?
#include?可能会重复包含,须要使用#pragram once 或者#ifdef 的方式来避免重复包含
#import没有这个问题,并且不会引发交叉编译
<>包含会从系统目录下开始寻找头文件
“”包含会优先从当前目录下寻找头文件,找不到再去系统目录下寻找。

4.ObjC中,与alloc语义相反的方法是dealloc仍是release?

retain语义相反的方法是dealloc仍是release,为何?
须要与alloc配对使用的方法是dealloc仍是release,为何?
答:alloc与dealloc语意相反,alloc是建立变量,dealloc是释放变量。
retain 对应release,retain 保留一个对象。调用以后,变量的计数加1。调用release后,变量的引用计数减1,当减为0时,dealloc方法会自动调用。咱们通常不显示地调用dealloc这个方法。
alloc 须要与release配对使用,由于alloc 这个函数调用以后,变量的计数加1。因此在调用alloc 以后,必定要调用对应的release。
另外,在release一个变量以后,他的值仍然有效,因此最好是后面紧接着再var = nil。

5.OC中加号方法与减号的区别?
答:加号方法是类方法 属于静态方法
减号方法是实例 必须由类的实例来调用

6.常见的object-c的数据类型有那些, 和C的基本数据类型有什么区别?如:NSInteger和int
object-c的数据类型有NSString,NSNumber,NSArray,NSMutableArray,NSData等等,这些都是class,建立后即是对象。
基本类型还有CGFloat,NSInteger等等。这些是为了之后兼容考虑。如今是32位NSInteger占4个字节,若是之后cpu升级了,之后int型占到8位了,不须要修改代码,还有NSInteger就能够作到。
C语言的基本数据类型int,只是必定字节的内存空间,用于存放数值;而object-c的NSNumber包含有父类NSObject的方法和NSNumber本身的方法,能够完成复杂的操做。

:objective-c与C++比较

嵌套调用方法:
objective-c [[[对象 方法1] 方法2] 方法3];函数调用顺序,依次由内向外用。
C++ 对象.方法1( ).方法2( ).方法3( );

方法调用形式:
objective-c [ 对象 方法名:参数A 方法名:参数B...];
C++ 对象.方法名(参数列表);
对象的建立:
objective-c 类名 对象指针=[[类名 alloc] 初始化方法];
C++ 类名 对象指针=new 构造方法;

空指针:
objective-c nil // 给空指针发送消息不会崩溃,只是没反应
C++ NULL //设用空指针的方法会崩溃

 

5、IOS面试之十大问题资深Cocoa开发

如下问题的答案依据本身的经验整理来,完善中。。。

1.你使用过Objective-C的运行时编程(Runtime Programming)么?若是使用过,你用它作了什么?你还能记得你所使用的相关的头文件或者某些方法的名称吗?
答:整个OC都是运行在一套Runtime基础之上的。不过大部分咱们不直接接触它的Runtime Programming.
咱们使用下面这些方法时,动态判断一个对象的类型,是否能对某个方法进行响应等等,都用到了OC的运行时特色。
- (BOOL)isKindOfClass:(Class)aClass;
- (BOOL)isMemberOfClass:(Class)aClass;
- (BOOL)conformsToProtocol:(Protocol *)aProtocol;
- (BOOL)respondsToSelector:(SEL)aSelector;
运行时的一个头文件是objc/runtime.h。
咱们能够利用里面的一些方法直接发送消息,如objc_msgSend().
也能够动态的给某个类添加方法,如class_addMethod().
甚至还能够动态添加一个类,如objc_addClass()。

2.你实现过多线程的Core Data么?NSPersistentStoreCoordinator,NSManagedObjectContext和NSManagedObject中的哪些须要在线程中建立或者传递?你是用什么样的策略来实现的?
答:没弄过。

3.Core开头的系列的内容。是否使用过CoreAnimation和CoreGraphics。UI框架和CA,CG框架的联系是什么?分别用CA和CG作过些什么动画或者图像上的内容。(有须要的话还能够涉及Quartz的一些内容)
答:涉及过一些。
UI框架内部仍是由CA和CG实现的。
CA作过一些view的描边操做,还有淡入淡出的转场动画。
CG作过一个画图程序,能够记录画笔的位置及线条颜色,能够合成一个UIImage.

4.是否使用过CoreText或者CoreImage等?若是使用过,请谈谈你使用CoreText或者CoreImage的体验。
答:没弄过。

5.NSNotification和KVO的区别和用法是什么?何时应该使用通知,何时应该使用KVO,它们的实现上有什么区别吗?若是用protocol和delegate(或者delegate的Array)来实现相似的功能可能吗?若是可能,会有什么潜在的问题?若是不能,为何?
KVO只能监测属性的变化,经过NSString类型的属性名来实现。可是实现了自动监测,当属性值变化时,会自动通知观察者,不用再添加代码了。
NSNotification比较灵活,能够监测的内容较多,可是须要被观察者手动发送通知,观察者才能响频。
protocol经过添加一个NSArray也能实现相似的功能,可是实现上须要本身处理delegate的添加与删除,本身在属性变化时手动通知,较繁琐,易出错。

6.你用过NSOperationQueue么?若是用过或者了解的话,你为何要使用NSOperationQueue,实现了什么?请描述它和GCD的区别和相似的地方(提示:能够从二者的实现机制和适用范围来描述)。

7.既然提到GCD,那么问一下在使用GCD以及block时要注意些什么?它们两是一回事儿么?block在ARC中和传统的MRC中的行为和用法有没有什么区别,须要注意些什么?

8.您是否作过异步的网络处理和通信方面的工做?若是有,能具体介绍一些实现策略么?
作过。
经过注册代码或者block的方式,实现回调。在网络处理方面,统一处理出错的状况,没出错的状况下,将数据分别发送给接收者。

9.对于Objective-C,你认为它最大的优势和最大的不足是什么?对于不足之处,如今有没有可用的方法绕过这些不足来实现需求。若是能够的话,你有没有考虑或者实践太重新实现OC的一些功能,若是有,具体会如何作?
优势: 与C,C++兼容,不少之前的类库能够不用修改直接使用。动态识别,比较灵活。加入类别,扩展方便。
缺点: 不支持重载和多继承,运行时致使效率稍低。
后面的问题没考虑那么多。

10.你实现过一个框架或者库以供别人使用么?若是有,请谈一谈构建框架或者库时候的经验;若是没有,请设想和设计框架的public的API,并指出大概须要如何作、须要注意一些什么方面,来使别人容易地使用你的框架。
答:曾经移植过一个框架,把C++的一套类库移植到OC上面,主要工做就是作一个oc++的接口层。作的过程当中,遇到的问题就是在原来框架中,不少头文件中用结构体或者类的地方,没有用指针,致使不能用声明的方式来使用类和结构体,必须在头文件中把其它头文件导入,这样致使整个接口须要提供的头文件太多了。
还封装过供他人调用的接口。建议就是调用方法尽量简单,作好传入参数的安全检查及错误提醒。由于你没法肯定你的调用者给你传什么样的数据进来。若是实现方法中耗时较长,须要用异步的方式进行结果返回,能够选用delegate或者block的方式。

 

6、开发经验及技巧

1. 下面请求数据用了什么协议,请求的数据格式是什么?
UIWebView *webView = [[UIWebView alloc] initWithFrame:self.view.frame];
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:http://pzpromop.s3.amazonaws.com/PromoNeutral.html]]];
[self.view addSubview:webView];
答:用了http协议,请求的数据格式是html文本。

2. 想传输一张图片,能够用什么协议传输?
答:http.

3.一个UITableView的实例,从新加载数据的方法是什么?
答:reloadData从新加载数据源中的所有数据
- (void)reloadSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation;
从新加载指定section中的数据
- (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;
从新加载指定行的数据

4.如何对iOS设备进行性能测试?
Profile-> Instruments ->Time Profiler

5. Object C中建立线程的方法是什么?若是在主线程中执行代码,方法是什么?若是想延时执行代码、方法又是什么?
答:线程建立有三种方法:使用NSThread建立、使用GCD的dispatch、使用子类化的NSOperation,而后将其加入NSOperationQueue;
在主线程执行代码,方法是performSelectorOnMainThread,
若是想延时执行代码能够用performSelector:onThread:withObject:waitUntilDone:或者dispatch_after或者NSTimer

6.建一个工程用到最基本的两个框架是什么?
答:UIKit框架 Foundation框架

7.若是UIView *view 已经实例化 在view 仅添加了N个UIButton类的实例,这些button不是全局的,而且button已经用tag区分开,如何快速找出其中指定的一个button改变它的某个属性?
答:[view viewWithTag:tagValue];

8.如何将产品进行多语言发布?
答:开发中xib针对每一个语言作一个。
字符串用NSLocalizedString宏包含起来
Make File Localizable

9.Animation的不一样形式,并加以代码示例.
答:枚举以下:
typedef NS_OPTIONS(NSUInteger, UIViewAnimationOptions) {
UIViewAnimationOptionLayoutSubviews = 1 << 0,
UIViewAnimationOptionAllowUserInteraction = 1 << 1, // turn on user interaction while animating
UIViewAnimationOptionBeginFromCurrentState = 1 << 2, // start all views from current value, not initial value
UIViewAnimationOptionRepeat = 1 << 3, // repeat animation indefinitely
UIViewAnimationOptionAutoreverse = 1 << 4, // if repeat, run animation back and forth
UIViewAnimationOptionOverrideInheritedDuration = 1 << 5, // ignore nested duration
UIViewAnimationOptionOverrideInheritedCurve = 1 << 6, // ignore nested curve
UIViewAnimationOptionAllowAnimatedContent = 1 << 7, // animate contents (applies to transitions only)
UIViewAnimationOptionShowHideTransitionViews = 1 << 8, // flip to/from hidden state instead of adding/removing

UIViewAnimationOptionCurveEaseInOut = 0 << 16, // default
UIViewAnimationOptionCurveEaseIn = 1 << 16,
UIViewAnimationOptionCurveEaseOut = 2 << 16,
UIViewAnimationOptionCurveLinear = 3 << 16,

UIViewAnimationOptionTransitionNone = 0 << 20, // default
UIViewAnimationOptionTransitionFlipFromLeft = 1 << 20,
UIViewAnimationOptionTransitionFlipFromRight = 2 << 20,
UIViewAnimationOptionTransitionCurlUp = 3 << 20,
UIViewAnimationOptionTransitionCurlDown = 4 << 20,
UIViewAnimationOptionTransitionCrossDissolve = 5 << 20,
UIViewAnimationOptionTransitionFlipFromTop = 6 << 20,
UIViewAnimationOptionTransitionFlipFromBottom = 7 << 20,
} NS_ENUM_AVAILABLE_IOS(4_0);
感受这个知道怎么查api就好,用的时候,能够直接查看头文件。

阅读(41)评论(0)
 
 

ios面试攻略(3.2)  

2013-10-27 11:19:06|  分类: IOS面试 |  标签:ios面试题目  |举报|字号 订阅

 
 

来自:蓝色维度

 

7、内存管理

1.objc的内存管理简介
(1)若是您经过分配和初始化(好比[[MyClass alloc] init])的方式来建立对象,您就拥有这个对象,须要负责该对象的释放。这个规则在使用NSObject的便利方法new 时也一样适用。
(2)若是您拷贝一个对象,您也拥有拷贝获得的对象,须要负责该对象的释放。
(3)若是您保持一个对象,您就部分拥有这个对象,须要在再也不使用时释放该对象。
(4)经过alloc,new, copy, retain的对象,retainCount+1;release或者autorelease后retainCount-1,若是retainCount为0时,对象会被消毁,dealloc方法被调用。
(5)谁拥有,谁管理;

2.什么是retain count?
答:引用计数(ref count或者retain count)。对象的内部保存一个数字,表示被引用的次数。
例如,某个对象被两个指针所指向(引用)那么它的retain count为2。须要销毁对 象的时候,不直接调用dealloc,而是调用release。release会 让retain count减1,只有retain count等于0,系统才会调用dealloc真正销毁这个对象。

3.自动释放池是什么,如何工做?
答:当您向一个对象发送一个autorelease消息时,Cocoa就会将该对象的一个引用放入到最新的自动释放池。它仍然是个正当的对象,所以自动释放池定义的做用域内的其它对象能够向它发送消息。当程序执行到做用域结束的位置时,自动释放池就会被释放,池中的全部对象也就被释放。

4.autorelease的对象是在何时被release的?
答:autorelease实际上只是把对release的调用延迟了,对于每个Autorelease,系统只是把该Object放入了当前的Autorelease pool中,当该pool被释放时,该pool中的全部Object会被调用Release。
对于每个Runloop, 系统会隐式建立一个Autorelease pool,这样全部的release pool会构成一个象CallStack同样的一个栈式结构,在每个Runloop结束时,当前栈顶的Autorelease pool会被销毁,这样这个pool里的每一个Object(就是autorelease的对象)会被release。

5.那什么是一个Runloop呢?
一个UI事件,Timer call, delegate call, 都会是一个新的Runloop。

6.如下每行代码执行后,person对象的retain count分别是多少
Person *person = [[Person alloc] init]; count 1
[person retain]; count 2
[person release];count 1
[person release];retain count = 1;

7.下面代码中obj2是否须要dealloc?
ClassA *obj1 = [[ClassA alloc] init];
ClassA *obj2 = obj1;
[obj1 hello]; //输出hello
[obj1 release];
[obj2 hello]; //程序可否执行到这一行?
[obj2 release];
答 不须要 他和obj2指向的是同一块空间

8.看下面的程序,第一个NSLog会输出什么?这时str的retainCount是多少?第二个和第三个呢? 为何?
NSMutableArray* ary = [[NSMutableArray array] retain];
NSString *str = [NSString stringWithFormat:@"test"];
[str retain];
[ary addObject:str];
NSLog(@”%@%d”,str,[str retainCount]);
[str retain];
[str release];
[str release];
NSLog(@”%@%d”,str,[str retainCount]);
[ary removeAllObjects];
NSLog(@”%@%d”,str,[str retainCount]);
答:
str的retainCount建立+1,retain+1,加入数组自动+1
3
retain+1,release-1,release-1
2
数组删除全部对象,全部数组内的对象自动-1
1

9.autorelease和垃圾回收机制(gc)有什么关系?
答:autorelase是用代码手写,在eventloop结束后被释放。
垃圾回收机制开启的话,你只用alloc,不用release,它会自动侦测一些你不用的对象,将它release掉。
可能在实现方式上或者说release的时机判断上有不一样,可是效果都是自动relase这个对象。

10.IPhone OS有没有垃圾回收(gc)?
没有。iPhone开发的时候没有垃圾回收机制,OC支持gc,但只限制在Mac OS上。

11.这段代码有什么问题,如何修改
for (int i = 0; i < someLargeNumber; i++)
{
NSString *string = @”Abc”;
string = [string lowercaseString];
string = [string stringByAppendingString:@"xyz"];
NSLog(@“%@”, string);
}
答:同时生成了大量autorelease对象,不利于内存管理。可是若是放在子线程的话,并且没有开启垃圾回收机制的话,则会形成内存泄露。
修改一:
for(int i = 0; i<somelargenumber;i++){
 NSAutoreleasePool * pool1 = [[NSAutoreleasePool alloc] init];
NSString *string = @"Abc";
string = [string lowercaseString];
string = [string stringByAppendingString:@"xyz"];
NSLog(@"%@",string);
[pool1 drain];
}
修改二:
NSAutoreleasePool * pool1 = [[NSAutoreleasePool alloc] init];
for(int i = 0; i<somelargenumber;i++){
 NSString *string = @"Abc";
string = [string lowercaseString];
string = [string stringByAppendingString:@"xyz"];
NSLog(@"%@",string);
}
[pool1 drain];
一点说明:
修改一的autoreleasePool的创建方法是考虑在若是每次循环生成大量的autorelease对象,这些对象占用很大内存的状况下,循环了1000次,那么这些全部的内存加起来就已经够程序崩溃了,那么这时候加在循环里面能够避免程序崩溃。
可是若是程序循环1000次生成的内存也不是不少,则能够用方法二,提升效率。
[pool drain][pool release]在没有垃圾回收机制的状况下,他们的效果是同样的。可是若是作mac开发并且开启了垃圾回收机制的话,要用drain而不是release,由于那种状况下用release只是把pool这个对象清理了,而pool里面的对象是没有被清理掉的

附:CoreFoundation部分
1)create,copy会造成own关系,不须要时应该CFRelease();
2) get方式获得的object,不造成own关系,不须要管理;
3)一个object做为参数传递到函数中后,receiver不与他造成own关系,也就是可能在任什么时候间被deallocate掉,因此须要CFRetain();
4)CFIndex count = CFGetRetainCount(obj);
5) myCFObj1 = myCFObj2-->引用拷贝,不会生成2个对象,应该使用CFStringCreatCopy()
6)符合的CF对象,copy时须要本身实现deep copy;

8、CocoaTouch

1.main.m中都发生了什么?
答:程序入口,建立 自动释放池,建立应用程序对象,并启动其主循环,运行程序,释放程序运行期间得全部加入自动释放池的对象。

2.int retVal = UIApplicationMain(argc, argv, nil, nil); 是什么意思?
答:UIApplication对象进行了初始化,这个方法除了argc 和 argv 参数外,另外这个函数还有两个字符串参数来识别UIApplication类和UIApplication代理类,在这里默认是2个nil,第一个参数为nil就默认把UIApplication类做为缺省值进行初始化,能够在这里不填nil而是使用本身定义的UIApplication子类。至于第二个参数nil就设置为nil就把模板生成的HelloWorldAppdelegate类做为默认值。

3.编写NSArray的setter和getter.
答:getter比较容易,直接返回NSArray的指针就能够了,
setter注意每一个元素加进去得时候须要retain一次。

4.什么是Notification?答:观察者模式,controller向defaultNotificationCenter添加本身的notification,其余类注册这个notification就能够收到通知,这些类能够在收到通知时作本身的操做(多观察者默认随机顺序发通知给观察者们,并且每一个观察者都要等当前的某个观察者的操做作完才能轮到他来操做,可用NotificationQueue的方式安排观察者的反应顺序,也能够在添加观察者中设定反映时间,取消观察须要在viewDidUnload 跟dealloc中都要注销)

5.多线程编程中,NSThread子线程与主线程的交互.
答:子线程内执行[self performSelectorOnMainThread:@selector(function:)withObject:];通知主线程执行相应方法。或者用全局变量的方式。

6.objective-c中是全部对象间的交互是如何实现的?(深圳皆凯科技有限公司笔试题)
答:在Objective-C中全部对象间的交互都是经过指针实现的,确切的说话,叫作发送消息。

8.objective-c中是如何实现线程同步的?
答:关键字@synchronized()

7.id 声明的对象有什么特性?
答:id 声明的对象具备运行时的特性,便可以指向任意类型的objcetive-c的对象;

8.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
网络/li>
Bonjour
WebKit
BSD Sockets
用户应用
Address Book
Core Location
Map Kit
Store Kit

 

9、设计模式

1.MVC模式的理解
MVC设计模式考虑三种对象:模型对象、视图对象、和控制器对象。模型对象表明特别的知识和专业技能,它们负责保有应用程序的数据和定义操做数据的逻辑。视图对象知道如何显示应用程序的模型数据,并且可能容许用户对其进行编辑。控制器对象是应用程序的视图对象和模型对象之间的协调者。

2.描述一下iOS SDK中如何实现MVC的开发模式
MVC是模型、视图、控制开发模式,对于iOS SDK,全部的View都是视图层的,它应该独立于模型层,由视图控制层来控制。全部的用户数据都是模型层,它应该独立于视图。全部的ViewController都是控制层,由它负责控制视图,访问模型数据。

3.类工厂方法是什么
类工厂方法的实现是为了向客户提供方便,它们将分配和初始化合在一个步骤中,返回被建立的对象,并进行自动释放处理。这些方法的形式是+ (type)className…(其中 className不包括任何前缀)。
工厂方法可能不只仅为了方便使用。它们不但能够将分配和初始化合在一块儿,还能够为初始化过程提供对象的分配信息。
类工厂方法的另外一个目的是使类(好比NSWorkspace)提供单件实例。虽然init…方法能够确认一个类在每次程序运行过程只存在一个实例,但它须要首先分配一个“生的”实例,而后还必须释放该实例。
工厂方法则能够避免为可能没有用的对象盲目分配内存。

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

 

10、操做系统

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

2.列举几种进程的同步机制,并比较其优缺点。
答案: 原子操做 信号量机制 自旋锁 管程,会合,分布式系统
进程之间通讯的途径
答案:共享存储系统消息传递系统管道:以文件系统为基础
进程死锁的缘由
答案:资源竞争及进程推动顺序非法
死锁的4个必要条件
答案:互斥、请求保持、不可剥夺、环路
死锁的处理
答案:鸵鸟策略、预防策略、避免策略、检测与解除死锁

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

 

11、杂项

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

2.目标-动做机制
目标是动做消息的接收者。一个控件,或者更为常见的是它的单元,以插座变量(参见”插座变量”部分)的形式保有其动做消息的目标。
动做是控件发送给目标的消息,或者从目标的角度看,它是目标为了响应动做而实现的方法。
程序须要某些机制来进行事件和指令的翻译。这个机制就是目标-动做机制。

3.什么是键-值,键路径是什么
模型的性质是经过一个简单的键(一般是个字符串)来指定的。视图和控制器经过键来查找相应的属性值。在一个给定的实体中,同一个属性的全部值具备相同的数据类型。键-值编码技术用于进行这样的查找—它是一种间接访问对象属性的机制。
键路径是一个由用点做分隔符的键组成的字符串,用于指定一个链接在一块儿的对象性质序列。第一个键的性质是由先前的性质决定的,接下来每一个键的值也是相对于其前面的性质。键路径使您能够以独立于模型实现的方式指定相关对象的性质。经过键路径,您能够指定对象图中的一个任意深度的路径,使其指向相关对象的特定属性。

4.何时用delegate,何时用Notification?
答:delegate针对one-to-one关系,而且reciever能够返回值给sender,
notification 能够针对one-to-one/many/none,reciever没法返回值给sender.
因此,delegate用于sender但愿接受到reciever的某个功能反馈值,notification用于通知多个object某个事件。

5.什么是KVC和KVO?
答:KVC(Key-Value-Coding)内部的实现:一个对象在调用setValue的时候,(1)首先根据方法名找到运行方法的时候所须要的环境参数。(2)他会从本身isa指针结合环境参数,找到具体的方法实现的接口。(3)再直接查找得来的具体的方法实现。
KVO(Key-Value-Observing):当观察者为一个对象的属性进行了注册,被观察对象的isa指针被修改的时候,isa指针就会指向一个中间类,而不是真实的类。因此isa指针其实不须要指向实例对象真实的类。因此咱们的程序最好不要依赖于isa指针。在调用类的方法的时候,最好要明确对象实例的类名。
其它回答:
kvc就是key value coding,简而言之就是根据key值改变它的内容,我以为很相似于dictionary。
kvo就是Key Value Observing,就是至关于你监控特定对象的特定key,当key对应的值发生改变时,会触发它的对应方法。
kvc实现(NSKeyValueCoding Protocol),最简单的方法就是setValue: forKey: 以及valueForKey:方法。例如你实现一个Person类,有两个property name,age,生成一个新对象p,能够用[p setValue:@"Solomon" forKey:@"name"];这样的方法进行赋值。
kvo实现(NSKeyValueObserving Protocol),–addObserver:forKeyPath:options:context:对你想要监控的对象,想要监控的属性添加一个observe,当值改变时,会触发– willChangeValueForKey:等方法。
kvc kvo结合使用,能够看成对对象属性值进行监控的一个notification,它对值进行监控。而notification也同时能够对消息响应之类 作出监控。
简单说KVC就是一个实现并扩展了setter/getter的方法集。

6.Notification和KVO有什么不一样?
KVO就是给属性添加一个监控器,当值发生改变的时候,给你一个接口去处理它。textView用过吧,当textView的值改变时,不也有一个textViewDidChange:的delegate方法么?
它就是一个NSObject的protocol,原本就是一个很简单的东西,不要想的很复杂化。这些东西的提出只是为了更方便,而不是它有什么特殊的含义,正如MVC同样。
notification也就是在程序检测event的loop里面加上一个跟踪事件的判断,若是接收到了这个事件,则作本身想要去作的事情。好比一个uiview的对象接收到一个触摸事件,它在系统检测event的无限循环里接收到了它,而后返回一个uitouch的事件让你去处理,从根本上来讲它和notification的性质同样的,虽然可能实现方式不尽相同,可是总归是跳不出这个圈子的。
固然,再往底层的东西,怎么去传递notification之类,苹果封装好了,你也不可能知道。就算你是苹果的程序员,由你来实现,也可能有不一样的方式来达到一样的目的。而这个已经超出了sdk编程的范围。

 
 
 
 
 
阅读(203)评论(0)
相关文章
相关标签/搜索