delegate和notification区别,分别在什么情况下使用?
Delegate:
消息的发送者(sender)告知接收者(receiver)某个事件将要发生,delegate同意然然后发送者响应事件,delegate机制使得接收者可以改变发送者的行为。通常发送者和接收者的关系是直接的一对一的关系。
Notification:
消息的发送者告知接收者事件已经发生或者将要发送,仅此而已,接收者并不能反过来影响发送者的行为。通常发送者和接收者的关系是间接的一对多或者多对多关系。
总结:三点
1.二者都用于传递消息,不同之处主要在于一个是一对一的,另一个是一对多或者多对多的。
2.delegate需要两者之间必须建立联系,不然没法调用代理的方法;notification不需要两者之间有联系,notification通过维护一个array,实现一对多消息的转发。两个模块之间联系不是很紧密,就用notification传值,例如多线程之间传值用notificaiton。delegate只是一种较为简单的回调,且主要用在一个模块中,例如底层功能完成了,需要把一些值传到上层去,就事先把上层的函数通过delegate传到底层,然后在底层call这个delegate,它们都在一个模块中,完成一个功能,例如说 NavgationController 从 B 界面到A 点返回按钮 (调用popViewController方法) 可以用delegate比较好。
3. 效率肯定是delegate比nsnotification高。
4. delegate方法比notification更加直接,最典型的特征是,delegate方法往往需要关注返回值,也就是delegate方法的结果。比如-windowShouldClose:,需要关心返回的是yes还是no。,根据返回值来决定如何做下一步.所以delegate方法往往包含should这个很传神的词。相反的,notification最大的特色就是不关心接受者的态度,我只管把通告放出来,你接受不接受就是你的事情,同时我也不关心结果。所以notification往往用did这个词汇,比如NSWindowDidResizeNotification,那么nswindow对象放出这个notification后就什么都不管了也不会等待接受者的反应。
36、你是如何理解delegate?
delegate,又称为委托或者代理,它是一种设计模式,delegate主要用于两个对象之间的通信交互,并且解除两个通信对象的耦合性,IOS中大量使用了delegate设计,主要用于视图与适用对象之间的通信交互。
delegate notification kvo三者比较
三种模式都是一个对象传递事件给另外一个对象,并且不要他们有耦合。三种模式都是对象来通知某个事件发生了的方法,或者更准确的说,是允许其他的对象收到这种事件的方法。
delegation
delegation的基本特征是,一个controller定义了一个协议(即一系列的方法定义)。该协议描述了一个delegate对象为了能够响应一个controller的事件而必须做的事情。协议就是delegator说,“如果你想作为我的delegate,那么你就必须实现这些方法”。实现这些方法就是允许controller在它的delegate能够调用这些方法,而它的delegate知道什么时候调用哪种方法。delegate可以是任何一种对象类型,因此controller不会与某种对象进行耦合,但是当该对象尝试告诉委托事情时,该对象能确定delegate将响应。
delegate的优势:
1.非常严格的语法。所有将听到的事件必须是在delegate协议中有清晰的定义。
2.如果delegate中的一个方法没有实现那么就会出现编译警告/错误
3.协议必须在controller的作用域范围内定义
4.在一个应用中的控制流程是可跟踪的并且是可识别的;
5.在一个控制器中可以定义定义多个不同的协议,每个协议有不同的delegates
6.没有第三方对象要求保持/监视通信过程。
7.能够接收调用的协议方法的返回值。这意味着delegate能够提供反馈信息给controller
缺点:
1.需要定义很多代码:1).协议定义;2).controller的delegate属性;3).在delegate本身中实现delegate方法定义
2.在释放代理对象时,需要小心的将delegate改为nil。一旦设定失败,那么调用释放对象的方法将会出现内存crash
3.在一个controller中有多个delegate对象,并且delegate是遵守同一个协议,但还是很难告诉多个对象同一个事件,不过有可能。
notification
IOS应用开发中有一个”Notification Center“的概念。它是一个单例对象,允许当事件发生时通知一些对象。它允许我们在低程度耦合的情况下,满足控制器与一个任意的对象进行通信的目的。这种模式的基本特征是为了让其他的对象能够接收到在该controller中发生某种事件而产生的消息,controller用一个key(通知名称)。这样对于controller来说是匿名的,其他的使用同样的key来注册了该通知的对象(即观察者)能够对通知的事件作出反应。
优势
1.不需要编写多少代码,实现比较简单;
2.对于一个发出的通知,多个对象能够做出反应,即1对多的方式实现简单
3.controller能够传递context对象(dictionary),context对象携带了关于发送通知的自定义的信息
缺点:
1.在编译期不会检查通知是否能够被观察者正确的处理;
2.在释放注册的对象时,需要在通知中心取消注册;
3.在调试的时候应用的工作以及控制过程难跟踪;
4.需要第三方对喜爱那个来管理controller与观察者对象之间的联系;
5.controller和观察者需要提前知道通知名称、UserInfo dictionary keys。如果这些没有在工作区间定义,那么会出现不同步的情况;
6.通知发出后,controller不能从观察者获得任何的反馈信息。
KVO
KVO是一个对象能够观察另外一个对象的属性的值,并且能够发现值的变化。前面两种模式更加适合一个controller与任何其他的对象进行通信,而KVO更加适合任何类型的对象侦听另外一个任意对象的改变(这里也可以是controller,但一般不是controller)。这是一个对象与另外一个对象保持同步的一种方法,即当另外一种对象的状态发生改变时,观察对象马上作出反应。它只能用来对属性作出反应,而不会用来对方法或者动作作出反应。
优点
1.能够提供一种简单的方法实现两个对象间的同步。例如:model和view之间同步;
2.能够对非我们创建的对象,即内部对象的状态改变作出响应,而且不需要改变内部对象(SKD对象)的实现;
3.能够提供观察的属性的最新值以及先前值;
4.用key paths来观察属性,因此也可以观察嵌套对象;
5.完成了对观察对象的抽象,因为不需要额外的代码来允许观察值能够被观察
缺点:
1.我们观察的属性必须使用strings来定义。因此在编译器不会出现警告以及检查;
2.对属性重构将导致我们的观察代码不再可用;
3.复杂的“IF”语句要求对象正在观察多个值。这是因为所有的观察代码通过一个方法来指向;
4.当释放观察者时不需要移除观察者。
使用任何一种模式都没有对和错,只有更适合或者不适合。每一种模式都给对象提供一种方法来通知一个事件给其他对象,而且前者不需要知道侦听者。在这三种模式中,我认为KVO有最清晰的使用案例,而且针对某个需求有清晰的实用性。而另外两种模式有比较相似的用处,并且经常用来给controller间进行通信。
使用命名规则好的协议和协议方法定义对于清晰的理解controllers间的通信是很容易的。努力的定义这些协议方法将增强代码的可读性,以及更好的跟踪你的app。代理协议发生改变以及实现都可通过编译器检查出来,如果没有将会在开发的过程中至少会出现crash,而不仅仅是让一些事情异常工作。甚至在同一事件通知多控制器的场景中,只要你的应用在controller层次有着良好的结构,消息将在该层次上传递。该层次能够向后传递直至让所有需要知道事件的controllers都知道。当然会有delegation模式不适合的例外情况出现,而且notification可能更加有效。例如:应用中所有的controller需要知道一个事件。然而这些类型的场景很少出现。另外一个例子是当你建立了一个架构而且需要通知该事件给正在运行中应用。
1 使用block和使用delegate完成委托模式有什么优点?
首先要了解什么是委托模式,委托模式在iOS中大量应用,其在设计模式中是适配器模式中的对象适配器,Objective-C中使用id类型指向一切对象,使委托模式更为简洁。了解委托模式的细节:
iOS设计模式—-委托模式
使用block实现委托模式,其优点是回调的block代码块定义在委托对象函数内部,使代码更为紧凑;
适配对象不再需要实现具体某个protocol,代码更为简洁。
7、block与函数有何异同,block有何优点
1>block类似于c里面的函数指针,都可以作为参数进行传递,用于回调,但block的定义可以在方法中,函数则不可以。
2>block语法简洁,可以在方法中定义实现,这样可以访问方法中的局部变量,使代码更加紧靠,结构简化。
13、Block在内存管理上的特点,需要注意循环引用,如何解决循环引用
1>、block块中使用了局部对象,则会将此对象retain,引用了当前对象的属性或者方法,则会将当前对象retain
2>、解决循环引用:将当前对象赋给一个局部变量,并且使用__block关键字修饰局部变量,使用该变量访问对象的属性和方法
2 多线程与block
GCD与Block
使用 dispatch_async 系列方法,可以以指定的方式执行block
GCD编程实例
dispatch_async的完整定义
void dispatch_async(
dispatch_queue_t queue,
dispatch_block_t block);
功能:在指定的队列里提交一个异步执行的block,不阻塞当前线程
通过queue来控制block执行的线程。主线程执行前文定义的 finishBlock对象 dispatch_async(dispatch_get_main_queue(),^(void){finishBlock();});
__block和__weak修饰符的区别其实是挺明显的:
1.__block不管是ARC还是MRC模式下都可以使用,可以修饰对象,还可以修饰基本数据类型。
2.__weak只能在ARC模式下使用,也只能修饰对象(NSString),不能修饰基本数据类型(int)。
3.__block对象可以在block中被重新赋值,__weak不可以。
tableView 滑动卡的问题主要是因为:从缓存中或者是从本地读取图片给UIImage的时候耗费的时间。需要把下面的两句话放到子线程里面:
- 1 NSData *imgData = [NSData dataWithContentsOfURL:[NSURL URLWithString:app.icon]]; //得到图像数据
- 2 UIImage *image = [UIImage imageWithData:imgData];
把UIImage赋值给图片的时候在主线程。
子线程不能更新UI 所有的UI跟新都是主线程执行了。手指滑动屏幕了。或者屏幕的某个方法执行了。
子线程里面加入NSTimer 的时候需要 手动添加NSRunloop 否则不能循环。
单利里面添加 NSMutableArray 的时候,防止多个地方对它同时便利和修改的话,需要加原子属性。并且用strong,,,并且写一个遍历和修改的方法。加上锁。 Lock UnLock
__weak ViewController* weakSelf = self;
GCD里面用 __weak 防止内存释放不了,循环引用。
UIViewController的生命周期
答:当一个视图控制器被创建,并在屏幕上显示的时候。 代码的执行顺序
// 视图显示在屏幕上的顺序
1、 alloc 创建对象,分配空间。
2、init (initWithNibName) 初始化对象,初始化数据。
3、loadView 从nib载入视图, 这一步不需要去干涉。除非没有使用xib文件创建视图。
4、viewDidLoad 加载完毕,可以进行自定义数据以及动态创建其他控件。
5、viewWillAppear 视图将出现在屏幕之前,马上这个视图即将显示在屏幕上。
6、viewDidAppear 视图已在屏幕上渲染完成。
// 视图将被从屏幕上移除的顺序
1、viewWillDisappear 视图将被从屏幕上移除之前执行。
2、viewDidDisappear 视图已经被从屏幕上移除。
3、dealloc 视图被销毁,此时需要在init和viewDidLoad中创建的对象进行释放。
4、viewDidUnload 出现内存警告在内存不足时执行,并对所有非当前显示的controller执行。
本视图的所有子视图将被销毁,以释放内存,此时开发者需要手动对viewLoad、viewDidLoad中创建的对象释放内存。
因为当这个视图再次显示在屏幕上的时候,viewLoad、viewDidLoad 再次被调用,以便再次构造视图
16.属性readwrite,readonly,assign,retain,copy,nonatomic 各是什么作用,在那种情况下用?
答:readwrite 是可读可写特性;需要生成getter方法和setter方法时
readonly 是只读特性 只会生成getter方法 不会生成setter方法 ;不希望属性在类外改变
assign 是赋值特性,setter方法将传入参数赋值给实例变量;仅设置变量时;
retain 表示持有特性,setter方法将传入参数先保留,再赋值,传入参数的retaincount会+1;
copy 表示赋值特性,setter方法将传入对象复制一份;需要完全一份新的变量时。
nonatomic 非原子操作,决定编译器生成的setter getter是否是原子操作,atomic表示多线程安全,一般使用non
11、strong 与weak,_unsafe_unretained与weak的区别
1>strong叫强引用,weak叫弱引用,在ARC中,使用strong告诉编译器帮助我们自动插入retain,weak是普通赋值相当于手动管理内存的assign;
2>_unsafe_unretained与weak功能一致,区别在于当指向的对象销毁后,weak会将变量置为nil,防止调用野指针。
1.什么情况使用 weak 关键字,相比 assign 有什么不同?
什么情况使用 weak 关键字?
1)在ARC中,在有可能出现循环引用的时候,往往要通过让其中一端使用weak来解决,比如:delegate代理属性
2)自身已经对它进行一次强引用,没有必要再强引用一次,此时也会使用weak,自定义IBOutlet控件属性一般也使用weak;当然,也可以使用strong。
不同点:
1)weak 此特质表明该属性定义了一种“非拥有关系” (nonowning relationship)。为这种属性设置新值时,设置方法既不保留新值,也不释放旧值。此特质同assign类似, 然而在属性所指的对象遭到摧毁时,属性值也会清空(nil out)。 而 assign 的“设置方法”只会执行针对“纯量类型” (scalar type,例如 CGFloat 或 NSlnteger 等)的简单赋值操作。
2)assigin 可以用非OC对象,而weak必须用于OC对象
2.这个写法会出什么问题: @property (strong) NSMutableArray *array;
使用了atomic属性会严重影响性能。
该属性使用了同步锁,会在创建时生成一些额外的代码用于帮助编写多线程程序,这会带来性能问题,通过声明nonatomic可以节省这些虽然很小但是不必要额外开销。
在默认情况下,由编译器所合成的方法会通过锁定机制确保其原子性(atomicity)。如果属性具备nonatomic特质,则不使用同步锁。请注意,尽管没有名为“atomic”的特质(如果某属性不具备nonatomic特质,那它就是“原子的”(atomic))。
在iOS开发中,你会发现,几乎所有属性都声明为nonatomic。
一般情况下并不要求属性必须是“原子的”,因为这并不能保证“线程安全” ( thread safety),若要实现“线程安全”的操作,还需采用更为深层的锁定机制才行。例如,一个线程在连续多次读取某属性值的过程中有别的线程在同时改写该值,那么即便将属性声明为atomic,也还是会读到不同的属性值。
因此,开发iOS程序时一般都会使用nonatomic属性。但是在开发Mac OS X程序时,使用 atomic属性通常都不会有性能瓶颈。
17.如何对iOS设备进行性能测试?
答:Profile-> Instruments ->Time Profiler
16、iOS开发中数据持久性,有哪几种?
plist文件写入、对象归档、sqlite3数据库、core data
18、简述常见的设计模式?
单例设计、代理设计、观察者(通知)、工厂方法、模版方法
24、@synthesize与dynamic的区别
1>@synthesize是系统自动生成getter和setter属性声明
2>@danamic的意思是告诉编译器,属性的获取与赋值方法由用户自己实现,不自动生成
20.Object C中创建线程的方法是什么?如果在主线程中执行代码,方法是什么?如果想延时执行代码、方法又是什么?
答:线程创建有三种方法:使用NSThread创建、使用 GCD的dispatch、使用子类化的NSOperation,然后将其加入NSOperationQueue;在主线程执行代码,方法是 performSelectorOnMainThread,如果想延时执行代码可以用performSelector:onThread:withObject:waitUntilDone:
24.浅复制和深复制的区别?//浅拷贝和深拷贝
答案:
浅层复制(copy):只复制指向对象的指针,而不复制引用对象本身。//通过对象的指针来访问这个对象深层复制(mutableCopy):复制引用对象本身意思就是有个A对象,复制一份后得到A_copy对象后,对于浅复制来说,A和A_copy指向的是同一个内存资源,复制的只不过是是一个指针,对象本身资源还是只有一份,那如果我们对A_copy执行了修改操作,那么发现A引用的对象同样被修改,这其实违背了我们复制拷贝的一个思想。深复制就好理解了,内存中存在了两份独立对象本身。//当修改A时,A copy不变。
27.类别的作用?继承和类别在实现中有何区别?
答:category 可以在不获悉,不改变原来代码的情况下往里面添加新的方法,只能添加,不能删除修改。
并且如果类别和原来类中的方法产生名称冲突,则类别将覆盖原来的方法,因为类别具有更高的优先级。类别主要有3个作用:
(1)将类的实现分散到多个不同文件或多个不同框架中。
(2)创建对私有方法的前向引用。
(3)向对象添加非正式协议。
继承可以增加,修改或者删除方法,并且可以增加属性
28.类别和类扩展的区别。
答:category和extensions的不同在于 后者可以添加属性。另外后者添加的方法是必须要实现的。extensions可以认为是一个私有的Category
29.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查找的逻辑理解,就说的过去了
35.ARC自动引用技术
答:1.ARC是编译特性,不是运行时特性,只是在编译的时候,编译器会自动加上释放代码
2.不能调用release、retain、autorelease、retainCount
3.dealloc注意
1> 不能在dealloc中调用[super dealloc]
2> 不能在dealloc中释放资源
4.@property参数说明
1> retain 改为 strong
2> 基本数据类型(intfloat)还是用assign
3> copy 还是 copy
4> 如果2个对象循环引用,一端用strong,一端用weak
5> weak是用在对象上,weak其实作用跟assign相当
5.ARC中只允许使用通过@autoreleasepool {}创建自动释放池
36 GCD技术
答:Grand Central Dispatch简称GCD 解决多核并行运算的一种方案
看代码就行:
// Grand Central Dispatch简称GCD技术
// Do any additional setup after loading the view.
// dispatch_queue_t newDispath = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// dispatch_async(newDispath, ^{
// [self downloadImage];
// });
// #defineDISPATCH_QUEUE_PRIORITY_HIGH 2
// #defineDISPATCH_QUEUE_PRIORITY_DEFAULT 0
// #defineDISPATCH_QUEUE_PRIORITY_LOW (-2)
// #defineDISPATCH_QUEUE_PRIORITY_BACKGROUNDINT16_MIN
/*dispatch queue分为下面三种:
* Serial:又称为private dispatch queues,同时只执行一个任务。Serial queue通常用于同步访问特定的资源或数据。当你创建多 个 Serial queue时,虽然它们各自是同步执行的,但Serial queue与Serial queue之间是并发执行的。
* Concurrent: 又称为global dispatch queue,可以并发地执行多个任务,但是执行完成的顺序是随机的。
* Main dispatch queue它是全局可用的serial queue,它是在应用程序主线程上执行任务的
*/
// 一般GCD 可以如下操作
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{
// 耗时的操作
dispatch_async(dispatch_get_main_queue(), ^{
// 更新界面
});
});
[selfexampleDispatch];
/*
*系统给每一个应用程序提供了三个concurrent dispatch queues。
*这三个并发调度队列是全局的,它们只有优先级的不同。
*因为是全局的,我们不需要去创建。我们只需要通过使用函数dispath_get_global_queue去得到队列
*/
dispatch_queue_t globalQ =dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
NSLog(@"global:%p",globalQ);
dispatch_queue_t mainQ =dispatch_get_main_queue();
NSLog(@"mainQ:%p",mainQ);
/*
*虽然dispatch queue是引用计数的对象,但是以上两个都是全局的队列,不用retain或release。
*/
/*
*dispatch_group_async可以实现监听一组任务是否完成,完成后得到通知执行其他的操作。
*这个方法很有用,比如你执行三个下载任务,当三个任务都下载完成后你才通知界面说完成的了。
*/
timeInt = 0;
[NSTimerscheduledTimerWithTimeInterval:1
target:self
selector:@selector(checkingTime)
userInfo:nil
repeats:YES];
[selfexampleDispath_group];
/*dispatch_barrier_async的使用
*dispatch_barrier_async是在前面的任务执行结束后它才执行,而且它后面的任务等它执行完成之后才会执行
*/
[selfexampleDispatch_barrier];
/*dispatch_apply
*执行某个代码片段N次。
*/
dispatch_apply(5, globalQ, ^(size_t index) {
// 执行5次
});
2.GCD 里面有哪几种 Queue? 背后的线程模型是什么样的?
GCD 中 Queue 的种类还要看我们怎么进行分类, 如果根据同一时间内处理的操作数分类的话, GCD 中的 Queue 分为两类
Serial Dispatch Queue
Concurrent Dispatch Queue
一类是串行派发队列, 它只使用一个线程, 会等待当前执行的操作结束后才会执行下一个操作, 它按照追加的顺序进行处理. 另一类是并行派发队列, 它同时使用多个线程, 如果当前的线程数足够, 那么就不会等待正在执行的操作, 使用多个线程同时执行多个处理.
另外的一种分类方式如下:
Main Dispatch Queue
Global Dispatch Queue
Custom Dispatch Queue
主线程只有一个, 它是一个串行的进程. 所有追加到 Main Dispatch Queue 中的处理都会在 RunLoop 在执行. Global Dispatch Queue 是所有应用程序都能使用的并行派发队列, 它有 4 个执行优先级 High, Default, Low, Background. 当然我们也可以使用 dispatch_queue_create 创建派发队列.
14. NSOperation队列
操作和操作队列,基本可以看成java中的线程和线程池的概念。用于处理ios多线程开发的问题。网上部分资料提到一点是,虽然是queue,但是却并不是带有队列的概念,放入的操作并非是按照严格的先进现出。这边又有个疑点是,对于队列来说,先进先出的概念是Afunc添加进队列,Bfunc紧跟着也进入队列,Afunc先执行这个是必然的,但是Bfunc是等Afunc完全操作完以后,B才开始启动并且执行,因此队列的概念离乱上有点违背了多线程处理这个概念。但是转念一想其实可以参考银行的取票和叫号系统。因此对于A比B先排队取票但是B率先执行完操作,我们亦然可以感性认为这还是一个队列。但是后来看到一票关于这操作队列话题的文章,其中有一句提到“因为两个操作提交的时间间隔很近,线程池中的线程,谁先启动是不定的。”瞬间觉得这个queue名字有点忽悠人了,还不如pool~综合一点,我们知道他可以比较大的用处在于可以帮组多线程编程就好了。
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)栈区:函数模块内申请,函数结束时由系统自动释放。存放局部变量、函数参数
15.const char *p; charconst*p; char*const p; const char* const p;四个修饰指针有什么区别
答: (1)定义了一个指向不可变的字符串的字符指针
(2)和(1)一样
(3)定义了一个指向字符串的指针,该指针值不可改变,即不可改变指向
(4)定义了一个指向不可变的字符串的字符指针,且该指针也不可改变指向
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 类或其子类。
38. UIView与CLayer有什么区别(10分)?
答: 1. UIView 是 iOS 系统中界面元素的基础,所有的界面元素都是继承自它。它本身完全是由 CoreAnimation 来实现的。它真正的绘图部分,是由一个 CALayer 类来管理。 UIView 本身更像是一个 CALayer 的管理器,访问它的跟绘图和跟坐标有关的属性。
2. UIView 有个重要属性 layer ,可以返回它的主 CALayer 实例。
3. UIView 的 CALayer 类似 UIView 的子 View 树形结构,也可以向它的 layer 上添加子layer ,来完成某些特殊的表示。即 CALayer 层是可以嵌套的。
4. UIView 的 layer 树形在系统内部,被维护着三份 copy 。分别是逻辑树,这里是代码可以操纵的;动画树,是一个中间层,系统就在这一层上更改属性,进行各种渲染操作;显示树,其内容就是当前正被显示在屏幕上得内容。
5. 动画的运作:对 UIView 的 subLayer (非主 Layer )属性进行更改,系统将自动进行动画生成,动画持续时间的缺省值似乎是 0.5 秒。
6. 坐标系统: CALayer 的坐标系统比 UIView 多了一个 anchorPoint 属性,使用CGPoint 结构表示,值域是 0~1 ,是个比例值。这个点是各种图形变换的坐标原点,同时会更改 layer 的 position 的位置,它的缺省值是 {0.5,0.5} ,即在 layer 的中央。
7. 渲染:当更新层,改变不能立即显示在屏幕上。当所有的层都准备好时,可以调用setNeedsDisplay 方法来重绘显示。
8. 变换:要在一个层中添加一个 3D 或仿射变换,可以分别设置层的 transform 或affineTransform 属性。
9. 变形: Quartz Core 的渲染能力,使二维图像可以被自由操纵,就好像是三维的。图像可以在一个三维坐标系中以任意角度被旋转,缩放和倾斜。 CATransform3D 的一套方法提供了一些魔术般的变换效果。
41. Quatrz 2D的绘图功能的三个核心概念是什么并简述其作用(10分)。
答:上下文:主要用于描述图形写入哪里;
路径:是在图层上绘制的内容;
状态:用于保存配置变换的值、填充和轮廓, alpha 值等。
42. iPhone OS主要提供了几种播放音频的方法(10分)?
答: SystemSound Services
AVAudioPlayer 类
Audio Queue Services
OpenAL
43. 使用AVAudioPlayer类调用哪个框架、使用步骤(10分)?
答: AVFoundation.framework
步骤:配置 AVAudioPlayer 对象;
实现 AVAudioPlayer 类的委托方法;
控制 AVAudioPlayer 类的对象;
监控音量水平;
回放进度和拖拽播放。
46. CFSocket使用有哪几个步骤(10分)。
答:创建 Socket 的上下文;创建 Socket ;配置要访问的服务器信息;封装服务器信息;连接服务器;
47. Core Foundation中提供了哪几种操作Socket的方法(10分)?
答: CFNetwork 、 CFSocket 和 BSD Socket 。
59. 线程与进程的区别和联系?
答案 : 进程和线程都是由操作系统所体会的程序运行的基本单元,系统利用该基本单元实现系统对应用的并发性。 程和线程的主要差别在于它们是不同的操作系统资源管理方式。进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。
60. ios 平台怎么做数据的持久化?coredata 和sqlite有无必然联系?coredata是一个关系型数据库吗?
iOS 中可以有四种持久化数据的方式:属性列表、对象归档、 SQLite3 和 Core Data; core 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 支持对一、对多的关系。
进程的同步机制,并比较其优缺点
(a)信号量机制: PV操作能够实现对临界区的管理要求;实现简单;允许使用它的代码休眠,持有锁的时间可相对较长。一个信号量只能置一次初值,以后只能对之进行p操作或v操作。由此也可以看到,信号量机制必须有公共内存,不能用于分布式操作系统,这是它最大的弱点。信号量机制功能强大,但使用时对信号量的操作分散, 而且难以控制,读写和维护都很困难。加重了程序员的编码负担;核心操作P-V分散在各用户程序的代码中,不易控制和管理;一旦错误,后果严重,且不易发现和纠正。
(b)自旋锁: 旋锁是为了保护共享资源提出的一种锁机制。调用者申请的资源如果被占用,即自旋锁被已经被别的执行单元保持,则调用者一直循环在那里看是否该自旋锁的保持着已经释放了锁。自旋锁是一种比较低级的保护数据结构和代码片段的原始方式,可能会引起以下两个问题; 1、死锁 2、过多地占用CPU资源 传统自旋锁由于无序竞争会导致“公平性”问题
(c)管程: 信号量机制功能强大,但使用时对信号量的操作分散,而且难以控制,读写和维护都很困难。因此后来又提出了一种集中式同步进程——管程。其基本思想是将共享变量和对它们的操作集中在一个模块中,操作系统或并发程序就由这样的模块构成。这样模块之间联系清晰,便于维护和修改,易于保证正确性。
(d)会合: 进程直接进行相互作用
(e)分布式系统: 由于在分布式操作系统中没有公共内存,因此参数全为值参,而且不可为指针。
(f)原语 是不可中断的过程。加锁/开锁(LOCK/UNLOCK)原语优点是实现互斥简单;缺点是效率很低
2.进程间通信的方式有______
(1)管道(Pipe):管道可用于具有亲缘关系进程间的通信,允许一个进程和另一个与它有共同祖先的进程之间进行通信。
(2)命名管道(named pipe):命名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信。命名管道在文件系统中有对应的文件名。命名管道通过命令mkfifo或系统调用mkfifo来创建。
(3)信号(Signal):信号是比较复杂的通信方式,用于通知接受进程有某种事件发生,除了用于进程间通信外,进程还可以发送信号给进程本身;linux除了支持Unix早期信号语义函数sigal外,还支持语义符合Posix.1标准的信号函数sigaction(实际上,该函数是基于BSD的,BSD为了实现可靠信号机制,又能够统一对外接口,用sigaction函数重新实现了signal函数)。
(4)消息(Message)队列:消息队列是消息的链接表,包括Posix消息队列system V消息队列。有足够权限的进程可以向队列中添加消息,被赋予读权限的进程则可以读走队列中的消息。消息队列克服了信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限等缺
(5)共享内存:使得多个进程可以访问同一块内存空间,是最快的可用IPC形式。是针对其他通信机制运行效率较低而设计的。往往与其它通信机制,如信号量结合使用,来达到进程间的同步及互斥。
(6)内存映射(mapped memory):内存映射允许任何多个进程间通信,每一个使用该机制的进程通过把一个共享的文件映射到自己的进程地址空间来实现它。
(7)信号量(semaphore):主要作为进程间以及同一进程不同线程之间的同步手段。
(8)套接口(Socket):更为一般的进程间通信机制,可用于不同机器之间的进程间通信。起初是由Unix系统的BSD分支开发出来的,但现在一般可以移植到其它类Unix系统上:Linux和System V的变种都支持套接字。
23.http和scoket通信的区别。
http是客户端用http协议进行请求,发送请求时候需要封装http请求头,并绑定请求的数据,服务器一般有web服务器配合(当然也非绝 对)。 http请求方式为客户端主动发起请求,服务器才能给响应,一次请求完毕后则断开连接,以节省资源。服务器不能主动给客户端响应(除非采取http长连接 技术)。iphone主要使用类是NSUrlConnection。
scoket是客户端跟服务器直接使用socket“套接字”进行连接,并没有规定连接后断开,所以客户端和服务器可以保持连接通道,双方 都可以主动发送数据。一般在游戏开发或股票开发这种要求即时性很强并且保持发送数据量比较大的场合使用。主要使用类是CFSocketRef。
TCP全称是Transmission Control Protocol,中文名为传输控制协议,它可以提供可靠的、面向连接的网络数据传递服务。传输控制协议主要包含下列任务和功能:
* 确保IP数据报的成功传递。
* 对程序发送的大块数据进行分段和重组。
* 确保正确排序及按顺序传递分段的数据。
* 通过计算校验和,进行传输数据的完整性检查。
5、TCP/IP 建立连接的过程
?
在TCP/IP 协议中,TCP协议提供可靠的连接服务,采用三次握手建立连接;
第一次握手:建立连接时,客户端发送连接请求到服务器,并进入SYN_SEND状态,等待服务器确认;
第二次握手:服务器收到客户端连接请求,向客户端发送允许连接应答,此时服务器进入SYN_RECV状态;
第三次握手:客户端收到服务器的允许连接应答,向服务器发送确认,客户端和服务器进入通信状态,完成三次握手。
(所谓的三次握手,就是要有三次连接信息的发送、接收过程。TCP连的建立需要进行三次连接信息的发送、接收。)
3、TCP/UDP区别联系
1>、TCP的全称为传输控制协议 这种协议可以提供面向连接的、可靠的、点到点的通信
2>、UDP的全称为用户数据报协议,它可以提供非连接的不可靠的点到多点的通信
3>、用TCP还是UDP,那要看你的程序注重南一方面? 可靠还是快速?
8.Objective-C如何对内存管理的,说说你的看法和解决方法?
Objective-C的内存管理主要有三种方式ARC(自动内存计数)、手动内存计数、内存池。
1. (Garbage Collection)自动内存计数:这种方式和java类似,在你的程序的执行过程中。始终有一个高人在背后准确地帮你收拾垃圾,你不用考虑它什么时候开始工作,怎样工作。你只需要明白,我申请了一段内存空间,当我不再使用从而这段内存成为垃圾的时候,我就彻底的把它忘记掉,反正那个高人会帮我收拾垃圾。遗憾的是,那个高人需要消耗一定的资源,在携带设备里面,资源是紧俏商品所以iPhone不支持这个功能。所以“Garbage Collection”不是本入门指南的范围,对“Garbage Collection”内部机制感兴趣的同学可以参考一些其他的资料,不过说老实话“Garbage Collection”不大适合适初学者研究。
解决: 通过alloc – initial方式创建的, 创建后引用计数+1, 此后每retain一次引用计数+1, 那么在程序中做相应次数的release就好了.
2. (Reference Counted)手动内存计数:就是说,从一段内存被申请之后,就存在一个变量用于保存这段内存被使用的次数,我们暂时把它称为计数器,当计数器变为0的时候,那么就是释放这段内存的时候。比如说,当在程序A里面一段内存被成功申请完成之后,那么这个计数器就从0变成1(我们把这个过程叫做alloc),然后程序B也需要使用这个内存,那么计数器就从1变成了2(我们把这个过程叫做retain)。紧接着程序A不再需要这段内存了,那么程序A就把这个计数器减1(我们把这个过程叫做release);程序B也不再需要这段内存的时候,那么也把计数器减1(这个过程还是release)。当系统(也就是Foundation)发现这个计数器变成了0,那么就会调用内存回收程序把这段内存回收(我们把这个过程叫做dealloc)。顺便提一句,如果没有Foundation,那么维护计数器,释放内存等等工作需要你手工来完成。
解决:一般是由类的静态方法创建的, 函数名中不会出现alloc或init字样, 如[NSString string]和[NSArray arrayWithObject:], 创建后引用计数+0, 在函数出栈后释放, 即相当于一个栈上的局部变量. 当然也可以通过retain延长对象的生存期.
3. (NSAutoRealeasePool)内存池:可以通过创建和释放内存池控制内存申请和回收的时机.
解决:是由autorelease加入系统内存池, 内存池是可以嵌套的, 每个内存池都需要有一个创建释放对, 就像main函数中写的一样. 使用也很简单, 比如[[[NSString alloc]initialWithFormat:@”Hey you!”] autorelease], 即将一个NSString对象加入到最内层的系统内存池, 当我们释放这个内存池时, 其中的对象都会被释放.
10、内存不足,系统会发出警告,此时控制器应该如何处理
内存不足时,系统会调用控制器的didReceiveMemoryWarning方法通知控制器内存不足。iOS6.0与6.0之前的处理方式不一样。
1>、6.0之前,调用didReceiveMemoryWarning后,将self.view设置为nil,并且再调用viewDidUnload方法,在此方法中我们应该释放子视图!
2>、6.0之后,调用didReceiveMemoryWarning后,不再调用viewDidUnload方法,则应该在didReceiveMemoryWarning方法中手动将self.view=nil,并且释放子视图!
40id、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,而不是对象)。
1.AFNetworking或SDWebImage 里面给 UIImageView 加载图片的逻辑是什么样的?
SDWebImage 中为 UIView 提供了一个分类叫做 WebCache, 这个分类中有一个最常用的接口, sd_setImageWithURL:placeholderImage: , 这个分类同时提供了很多类似的方法, 这些方法最终会调用一个同时具有 option progressBlock completionBlock 的方法, 而在这个类最终被调用的方法首先会检查是否传入了 placeholderImage 以及对应的参数, 并设置 placeholderImage .
然后会获取 SDWebImageManager 中的单例调用一个 downloadImageWithURL:... 的方法来获取图片, 而这个 manager 获取图片的过程有大体上分为两部分, 它首先会在 SDWebImageCache 中寻找图片是否有对应的缓存, 它会以 url 作为数据的索引先在内存中寻找是否有对应的缓存, 如果缓存未命中就会在磁盘中利用 MD5 处理过的 key 来继续查询对应的数据, 如果找到了, 就会把磁盘中的缓存备份到内存中.
然而, 假设我们在内存和磁盘缓存中都没有命中, 那么 manager 就会调用它持有的一个 SDWebImageDownloader 对象的方法 downloadImageWithURL:... 来下载图片, 这个方法会在执行的过程中调用另一个方法 addProgressCallback:andCompletedBlock:fotURL:createCallback: 来存储下载过程中和下载完成的回调, 当回调块是第一次添加的时候, 方法会实例化一个 NSMutableURLRequest 和 SDWebImageDownloaderOperation , 并将后者加入 downloader 持有的下载队列开始图片的异步下载.
而在图片下载完成之后, 就会在主线程设置 image, 完成整个图像的异步下载和配置.
4.什么是iOS中的沙盒机制。
IOS中的沙盒机制(SandBox)是一种安全体系,它规定了应用程序只能在为该应用创建的文件夹内读取文件,不可以访问其他地方的内容。
1.每个应用程序都在自己的沙盒内
2.不能随意跨越自己的沙盒去访问别的应用程序沙盒的内容
3.应用程序向外请求或接收数据都需要经过权限认证
默认情况下,每个沙盒含有3个文件夹:Documents, Library 和 tmp。因为应用的沙盒机制,应用只能在几个目录下读写文件
Documents:苹果建议将程序中建立的或在程序中浏览到的文件数据保存在该目录下,iTunes备份和恢复的时候会包括此目录
Library:存储程序的默认设置或其它状态信息;
Library/Caches:存放缓存文件,iTunes不会备份此目录,此目录下文件不会在应用退出删除
tmp:提供一个即时创建临时文件的地方
4.nil, Nil, NSNULL, NULL区别
nil是指向obj-c中对象的空指针,是一个对象,在o-c中ni对象调用方法不会引起crash。
Nil是指向obj-c中的类的空指针,表示的是一个空类。
NULL是指向任何类型的空指针(如c/c++中的空指针),在objective-c中是一个数值。
NSNULL用于集合操作,在集合对象中,表示一个空值的集合对象。
5.iOS中处理音频和视频使用哪些框架?
AVFoundation(基于Core Audio、Core Video、Core Media等框架)、MediaPlayer、UIKit
1.如何监听View的触摸事件,事件是如何传递的、视图的响应者链是什么?
(1)覆写View类的touchBegin、touchMove、touchEnd系列方法监听视图的触摸。
(2)事件传递:当触摸一个视图时,首先系统会捕捉此事件,并为此事件创建一个UIEvent对 象,将此对象加入当前应用程序的事件队列中,然后由UIApplication对象从队列中,一个一个取出来进⾏分发,⾸首先分发给UIWindow对象,然后由UIWindow对象分发给触摸的视图对 象,也就是第一响应者对象。!
(3)响应者链: 事件被交由第一响应者对象处理,如果第一响应者不处理,事件被沿着响应 者链向上传递,交给下一个响应者(next responder)。一般来说,第一响应者是个视图对 象或者其子类对象,当其被触摸后事件被交由它处理,如果它不处理,事件就会被传递给它 的视图控制器对象(如果存在),然后是它的父视图(superview)对象(如果存在),以 此类推,直到顶层视图。接下来会沿着顶层视图(top view)到窗⼝口(UIWindow对象)再 到程序(UIApplication对象)。如果整个过程都没有响应这个事件,该事件就被丢弃。一般 情况下,在响应者链中只要由对象处理事件,事件就停⽌传递。但有时候可以在视图的响应 ⽅方法中根据一些条件判断来决定是否需要继续传递事件。
25、响应者链的概念
响应者链表示一系列的响应者对象。事件被交由第一响应者对象处理,如果第一响应者不处理,事件被沿着响应者链向上传递,交给下一个响应者(next responder)。一般来说,第一响应者是个视图对象或者其子类对象,当其被触摸后事件被交由它处理,如果它不处理,事件就会被传递给它的视图控制器对象(如果存在),然后是它的父视图(superview)对象(如果存在),以此类推,直到顶层视图。接下来会沿着顶层视图(top view)到窗口(UIWindow对象)再到程序(UIApplication对象)。如果整个过程都没有响应这个事件,该事件就被丢弃。一般情况下,在响应者链中只要由对象处理事件,事件就停止传递。但有时候可以在视图的响应方法中根据一些条件判断来决定是否需要继续传递事件。
3、c语言中extern的作用,extern c的作用?
1>extern可以置于变量或者函数前,以标示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义
2>c++语言在编译的时候为了解决函数的多态问题,会将函数名和参数联合起来生成一个中间的函数名称,而c语言则不会,因此会造成链接时找不到对应函数的情况,此时c函数就需要extern“C”进行链接指定,这告诉编译器,请保持我的名称,不要给我生成用于链接的中间函数名
2.xml数据的解析方式,各有什么不同?
(1)xml数据解析有两种解析⽅方式:DOM解析与SAX解析!
(2)DOM解析必须先完成DOM树的构造,在处理规模较大的XML文档时就很耗内存,占⽤资 源较多!
(3)与DOM不同的是,它是⽤用事件驱动模型,解析XMl⽂文档时每遇到一个开始或者结束标 签、 或者属性、或者一条指令时,程序就产⽣生一个事件来进⾏行相应的处理,因此,SAX相对于 DOM来说更适合操作⼤的XML文档!
1.Core Graphics 和Quartz 2D的区别?
quartz是一个通用的术语,用于描述在IOS和MAC OS X ZHONG 整个媒体层用到的多种技术 包括图形、动画、音频、适配。
Quart 2D 是一组二位绘图和渲染API,Core Graphic会使用到这组API
Quartz Core 专指Core Animation用到的动画相关的库、API和类。
39、Cocoa Touch框架
UIKit、Foundation、CoreGraphic、QuartzCore
1>音频和视频
Core Audio
OPenAL
Media Library
AV Foundation
2>数据管理
Core Data
SQLite
3>图形和动画
Core Animation
OpenGL ES
Quartz 2D
4>用户应用
Address Book
Core Location
Map Kit
Store Kit
47、单例设计模式的实现,为什么使用单例设计
static File * instance = nil;
@implementation File
//获取单例的方法
+(id)shareInstance
{
@synchronized(self)
{
if(instance == nil)
{
instance = [[File alloc]init];
}
}
return instance;
}
覆写allocWithZone、copyWithZone、retain、authorelease 方法,目的是限制这个类只创建一个对象
19、用过哪些开源网络框架各有什么特点
1>、ASIHTTPRequest
优点:出来比较早、功能强大、文档丰富(目前很多应用还在使用)
缺点:已经停止更新、新特性少、厚重且对iOS5以上支持不够完善。
2>、AFNetWorking
优点:支持比较新的特性、简单易用
缺点:文档数目一般、功能少、忽略拉一些扩展功能(如:没有同步请求)
3>、MKNetWorking
优点:支持arc、一个印度大卡写的。有ASIHTTPRequest的功能,AFNetWorking的轻便
缺点:文档数目最少(几乎没有)
28、ASI网络框架有哪些功能?
1>、ASI是款极其强劲的HTTP访问开源框架;
2>、功能:异步请求 队列请求 gzip压缩 缓存 断点续传 进度跟踪 上传文件 HTTP认证
20、iOS中有哪些数据持久化的方式,各有什么特点,ios平台怎么做数据的持久化?CoreData 和sqlite有无必然的联系?CoreData是一个关系型数据库吗?
1>、主要有四种持久化方式:属性列表、对象归档、SQLLite、coredata。
2>、CoreData不是一个数据库,不过可以使用SQLLite数据库来保持数据,也可以使用其他的方式存储数据,如XML。
3>、属性列表、对象归档适合小数据量存储和查询操作。
4>、SQLite、CoreData适合大数据存储和查询操作。
21、iPhone5如何适配
1>、添加启动图片,Default-568h@2x.png 分辨率640*1136 pixels
2>、在编码时,尽量不要写死480*320的尺寸,使用UIScreen获取硬件的物理尺寸
3>、通过设置autosizing 来适应在父视图中的frame
22、iOS中如何捕捉异常
@try{}
@catch{}
23、用过单元测试吗
iOS自带了一个测试框架OCUnit,但目前最好用的测试框架应该是GHUnit
25、苹果APP的上架流程、什么情况下会被打回
1>、访问私有API
2>、APP有严重deBUG
3>、给苹果审核的测试账号无法登陆,或者境外无法访问国内服务器
4>、APP描述中带“Beta”字样,或是其他表明APP还未开发完成的信息
5>、APP加载时间过长,iOS APP的最长启动时间不得超过15秒
6>、给出外部购买链接
7>、APP描述中提到了iOS之外的其他支持平台
26、tableView是如何复用的?
如果屏幕上能显示10个单元格,则tableView只会创建11个单元格,也就是n+1,当滑到第12个单元格时就会复用第1个单元格对象。tableView中有个单元格池这么一个概念,tableView调用协议方法获取单元格时,先从池子中查找是否有可复用的单元格,如果有则复用,没有则创建一个单元格对象
27、如何优化tableView的滑动速度
1>、复用单元格;
2>、使用不透明的视图,单元格中尽量少使用动画;
3>、图片加载使用异步加载,并且设置图片加载的并发数;
4>、滑动时不加载图片,停止滑动开始加载;
5>、文字,图片可以直接drawInRect绘制;
6>、如非必要,减少reloadData全部的cell,只reloadRowsAtIndexPaths;
7>、如果Cell是动态行高,计算出高度后缓存;
8>、Cell高度固定的话直接cell.rowHeight设置高度
31、如何将产品进行多语言发布,做国际化开发
1>、新建String File文件,命名为 Localizable.strings, 往里面添加你想要的语言支持
2>、在不同语言的 Localizable.strings文件中添加对应的文本
3>、XIB文件国际化
4>、程序名称国际化
参考:http://hi.baidu.com/yunhuaikong/item/d8e8e2e4be13a8088c3ea829
37、iOS中都有哪些手势
iOS提供了很多手势对象用于识别不同的手势操作,手势:轻击,捏合,平移,轻扫,旋转,长按
40、二维码扫描用过哪些类库,这些类库有什么特点?
二维码生成:QRGener
二维码扫描:zxing,ZBarSDK
二维码扫描:推荐使用zxing,因为zxing可以自定义扫描区域,而且是开源的,但是这个库集成起来比较复杂
44、StoryBoard用过吗,有什么特点?
1>、StoryBoard是iOS5新增的特性,是对xib的升级版本,引入了一个容器用于管理多个xib文件,和他们之间的跳转交互
2>、有点:不用在为每个控制器创建xib文件了
3>、缺点: StoryBoard单个文件,不利于团队协作开发
45、如何打包静态库?
新建一个Framework&Library的项目,编译的时候,会将项目中的代码文件打包成一个.a的静态库文件
46、App发布的上架流程?
1>、在苹果网站的开发者中心,新建一个App,填写此APP相关的一些描述信息
2>、下载安装发布证书
3>、选择发布证书,是与Archive生成发布包
4>、使用xcode提交发布包
- 什么是序列化或者Archiving?可以用来作甚么?怎么和copy结合?原理是什么?
答:序列化是将对象状态转换为可保持或传输的格式的过程,在序列化过程中,对象的公共字段和私有字段以及类的名称(包括包含该类的程序集)都被转换为字节流,然后写入数据流。与序列化相对的是反序列化,它将流转换为对象。这两个过程结合起来,可以轻松地存储和传输数据。(在iphone中要实现对象序列化,首相被序列化的对象必须NSCodeing 协议和NSCopying 协议,并分别实现两个协议的方法:NSCoding- (void)encodeWithCoder:(NSCoder *)encoder; - (id)initWithCoder:(NSCoder *)decoder #NSCoding:- (id)copyWithZone:(NSZone *)zone )
为什要对象序列化?a. 一个原因是将对象的状态保持在存储媒体中,以便可以在以后重新创建精确的副本。
我们经常需要将对象的字段值保存到磁盘中,并在以后检索此数据。尽管不使用序列化也能完成这项工作,但这种方法通常很繁琐而且容易出错,并且在需要跟踪 对象的层次结构时,会变得越来越复杂。可以想象一下编写包含大量对象的大型业务应用程序的情形,程序员不得不为每一个对象编写代码,以便将字段和属性保存 至磁盘以及从磁盘还原这些字段和属性。序列化提供了轻松实现这个目标的快捷方法。
b.另一个原因是通过值将对象从一个应用程序域发送到另一个应用程序域中。
例如,序列化可用于在 ASP.NET 中保存会话状态并将对象复制到 Windows 窗体的剪贴板中。远程处理还可以使用序列化通过值将对象从一个应用程序域传递到另一个应用程序域中。
- 线程是什么?有哪些注意事项?
答:线程是一组指令集合,或者是程序的特殊段,它可以在程序里独立执行,也可把它理解为代码运行的上下文,线程是在同一时间需要完成多项任务的时候被实现的。
,进程和线程都是由操作系统所体会的程序运行的基本单元,系统利用该基本单元实现系统对应用的并发性.简而言之,一个程序至少有一个进程,一个进程至少有一个线程.
线程的划分尺度小于进程,使得多线程程序的并发性高。
另外,进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率
注意多线程数据共享管理的问题和死锁问题(造成死锁的4个必备条件:互斥、请求保持、不可剥夺、环路),怎样解决死锁问题? 答案:鸵鸟策略、预防策略、避免策略、检测与解除死锁
Iphone代码上怎么解决死锁问题?创建操作队列NSOperationQueue(相当于java中的线程池)用操作队列来管理多个任务对象(继承自NSOperation),每个任务对象去各自完成自己的行为。。。。
- Runloop是什么?在主线程里的某一个函数里调用了一个异步函数,怎么样block当前线程,而且还能响应当前线程的timer事件,touch事件等。
答:每个线程内部都有自己的Run loop(这里不是指特定类,就是一个循环)。
线程常见的情况如下
while(stopThread_bool){
}
就是这个循环。
既然obj-c有runtime能力,所以apple就开发了 NSRunLoop 类,来管理线程内的循环,可以在程序运行时添加,删除和修改loop内的代码 。当然同时NSRunLoop有MainThread循环的管理功能,这样你可以给MainThread runloop里面插入你自己希望执行的代码(一般情况是界面更新有关的函数)。亦或给自己定义的thread加入一个NSRunLoop对象,动态管理线程执行的代码。
这样一个线程内的代码可能会
while(stopThread_bool){
//custom code
NSArray *funArray=[[self runloopObj] loopFunArray];
foreach(fun in funArray){
[self performSeletor:@selector(fun)];
}
}
以上是一个假想的Thread和它的NSRunLoop实例交互的伪代码。
1.首先你要看到你认识上的问题,在书里介绍的runloop != while or for语句
2.每个线程都有自己的NSRunLoop,他们是自己建立的
3.并不是所以线程都需要使用它的NSRunLoop. 如果线程的runloop没有自己的input source,它不会运行。
4.以下几个情况是需要用线程的runloop
Use ports or custom input sources to communicate with other threads.
Use timers on the thread.
Use any of the performSelector… methods in a Cocoa application.
Keep the thread around to perform periodic tasks.
5. - (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait 这样的语句实际上就是在向Main Thread的runloop对象添加input source.
我不知道怎么解释你才能更清楚,也许你可以再多说说你不理解的地方。
另一个说法:runloop一个UI事件,Timer call, delegate call,都会是一个新的runloop。