最近面试,与你们分享一下,分三文给你们:html
固然Xcode新版本区别,以及iOS新特性java
Xcode8 和iOS 10 在以前文章有发过,感兴趣的能够查阅: http://www.cnblogs.com/xujiahui/p/6025830.htmlios
之二:c++
1.怎么样适配ios系统和ios屏幕程序员
ios适配系统代码写法[[UIDevice currentDevice] systemVersion] 和NSFoundationVersionNumber也能够在base SDK 中修改版本号web
ios8中NSProcessInfo -isOperatingSystemAtLeastVersion面试
(StatusBar)StatusBarHeight 的高度 ios7之后 StatusBar是悬浮在屏幕上方的 因此ios7以后控件布局须要加上20 而在ios7以前不须要objective-c
label的文本自适应须要适配sql
(ios8适配)UIAlertController UIAlertAction —ios8 代替了 UIAlertView数据库
(ios8适配)ios8新增定位判断,info.plist文件设置两个属性 用到定位须要适配
ios屏幕适配 用Masonry等,我的喜欢这个屏幕尺寸大小 http://www.cnblogs.com/xujiahui/p/6042519.html
2.什么是静态库 静态库和动态库的区别
程序编译通常需经预处理、编译、汇编和连接几个步骤。在咱们的应用中,有一些公共代码是须要反复使用,就把这些代码编译为“库”文件;在连接步骤中,链接器将从库文件取得所需的代码,复制到生成的可执行文件中。这种库称为静态库,其特色是可执行文件中包含了库代码的一份完整拷贝;缺点就是被屡次使用就会有多份冗余拷贝。
静态库和动态库是两种共享程序代码的方式,它们的区别是:静态库在程序的连接阶段被复制到了程序中,和程序运行的时候没有关系;动态库在连接阶段没有被复制到程序中,而是程序在运行时由系统动态加载到内存中供程序调用。使用动态库的优势是系统只需载入一次动态库,不一样的程序能够获得内存中相同的动态库的复本,所以节省了不少内存。
3.ViewController声明周期
ViewController生命周期中有那么多函数,一个重要问题就是什么代码该写在什么地方。
一、init里不要出现建立view的代码。良好的设计,在init里应该只有相关数据的初始化,并且这些数据都是比较关键的数据。init里不要掉self.view,不然会致使viewcontroller建立view。(由于view是lazyinit的)。
二、loadView中只初始化view,通常用于建立比较关键的view如tableViewController的tabView,UINavigationController的navgationBar,不可掉用view的getter(在掉super loadView前),最好也不要初始化一些非关键的view。若是你是从nib文件中建立的viewController在这里必定要首先调用super的loadView方法,但建议不要重载这个方法。
三、viewDidLoad 这时候view已经有了,最适合建立一些附加的view和控件了。有一点须要注意的是,viewDidLoad会调用屡次(viewcontroller可能屡次载入view,参见图2)。
四、viewWillAppear 这个通常在view被添加到superview以前,切换动画以前调用。在这里能够进行一些显示前的处理。好比键盘弹出,一些特殊的过程动画(好比状态条和navigationbar颜色)。
五、viewDidAppear 通常用于显示后,在切换动画后,若是有须要的操做,能够在这里加入相关代码。
六、viewDidUnload 这时候viewController的view已是nil了。因为这通常发生在内存警告时,因此在这里你应该将那些不在显示的view释放了。好比你在viewcontroller的view上加了一个label,并且这个label是viewcontroller的属性,那么你要把这个属性设置成nil,以避免占用没必要要的内存,而这个label在viewDidLoad时会从新建立。
4.Object-c的类能够多重继承么?能够实现多个接口么?Category是什么?重写一个类的方式用继承好仍是分类好?为何?
答: Object-c的类不能够多重继承;能够实现多个接口,经过实现多个接口能够完成C++的多重继承;Category是类别,通常状况用分类好,用Category去重写类的方法,仅对本Category有效,不会影响到其余类与原有类的关系。没有,cocoa 中全部的类都是NSObject 的子类,多继承在这里是用protocol 委托代理来实现的? ,ood的多态特性在obj-c中经过委托来实现。
5. #import 跟#include 又什么区别,@class呢, #import<> 跟 #import””又什么区别?
答:#import是Objective-C导入头文件的关键字,#include是C/C++导入头文件的关键字,使用#import头文件会自动只导入一次,不会重复导入,至关于#include和#pragma once;@class告诉编译器某个类的声明,当执行时,才去查看类的实现文件,能够解决头文件的相互包含;#import<>用来包含系统的头文件,#import””用来包含用户头文件。
6. 属性readwrite,readonly,assign,retain,copy,nonatomic 各是什么做用,在那种状况下用?
1. readwrite 是可读可写特性;须要生成getter方法和setter方法时
2. readonly 是只读特性 只会生成getter方法 不会生成setter方法 ;不但愿属性在类外改变
3. assign 是赋值特性,setter方法将传入参数赋值给实例变量;仅设置变量时;
4. retain 表示持有特性,setter方法将传入参数先保留,再赋值,传入参数的retaincount会+1;
5. copy 表示赋值特性,setter方法将传入对象复制一份;须要彻底一份新的变量时。
6. nonatomic 非原子操做,决定编译器生成的setter getter是不是原子操做,atomic表示多线程安全,通常使用nonatomic
7.写一个setter方法用于完成@property (nonatomic,retain)NSString *name,写一个setter方法用于完成@property(nonatomic,copy)NSString *name
- (void) setName:(NSString*) str
{
[str retain];
[name release];
name = str;
}
- (void)setName:(NSString *)str
{
id t = [str copy];
[name release];
name = t;
}
8.对于语句NSString*obj = [[NSData alloc] init]; obj在编译时和运行时分别时什么类型的对象?
编译时是NSString的类型;运行时是NSData类型的对象
9.常见的object-c的数据类型有那些, 和C的基本数据类型有什么区别?如:NSInteger和int
object-c的数据类型有NSString,NSNumber,NSArray,NSMutableArray,NSData等等,这些都是class,建立后即是对象,而C语言的基本数据类型int,只是必定字节的内存空间,用于存放数值;NSInteger是基本数据类型,并非NSNumber的子类,固然也不是NSObject的子类。NSInteger是基本数据类型Int或者Long的别名(NSInteger的定义typedef long NSInteger),它的区别在于,NSInteger会根据系统是32位仍是64位来决定是自己是int仍是Long。
10.id 声明的对象有什么特性?
Id 声明的对象具备运行时的特性,便可以指向任意类型的objcetive-c的对象;
没有 * 号
动态数据类型
能够指向任何类的对象(设置是nil),而不关心其具体类型
在运行时检查其具体类型
能够对其发送任何(存在的)消息
11.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对象加入到最内层的系统内存池, 当咱们释放这个内存池时, 其中的对象都会被释放.
12. 原子(atomic)跟非原子(non-atomic)属性有什么区别?
1. atomic提供多线程安全。是防止在写未完成的时候被另一个线程读取,形成数据错误
2. non-atomic:在本身管理内存的环境中,解析的访问器保留并自动释放返回的值,若是指定了 nonatomic ,那么访问器只是简单地返回这个值。
13. 看下面的程序,第一个NSLog会输出什么?这时str的retainCount是多少?第二个和第三个呢? 为何?
NSMutableArray* ary = [[NSMutableArray array] retain];
NSString *str = [NSString stringWithFormat:@"test"];
[strretain];
[aryaddObject:str];
NSLog(@”%@%d”,str,[str retainCount]);
[strretain];
[strrelease];
[strrelease];
NSLog(@”%@%d”,str,[str retainCount]);
[aryremoveAllObjects];
NSLog(@”%@%d”,str,[str retainCount]);
str的retainCount建立+1,retain+1,加入数组自动+1 3
retain+1,release-1,release-1 2
数组删除全部对象,全部数组内的对象自动-1 1
14. 内存管理的几条原则时什么?按照默认法则.那些关键字生成的对象
须要手动释放?在和property结合的时候怎样有效的避免内存泄露?
谁申请,谁释放
遵循Cocoa Touch的使用原则;
内存管理主要要避免“过早释放”和“内存泄漏”,对于“过早释放”须要注意@property设置特性时,必定要用对特性关键字,对于“内存泄漏”,必定要申请了要负责释放,要细心。
关键字alloc 或new 生成的对象须要手动释放;
设置正确的property属性,对于retain须要在合适的地方释放,
15.如何对iOS设备进行性能测试?
Profile-> Instruments ->Time Profiler
16. Object C中建立线程的方法是什么?若是在主线程中执行代码,方法是什么?若是想延时执行代码、方法又是什么?
线程建立有三种方法:使用NSThread建立、使用GCD的dispatch、使用子类化的NSOperation,而后将其加入NSOperationQueue;在主线程执行代码,方法是performSelectorOnMainThread,若是想延时执行代码能够用performSelector:onThread:withObject:waitUntilDone:
GCD从语言、运行时库、系统扩展等三个方面给让使用者更充分的操做多核设备,同时它基于队列的概念,由于每个CPU core单位时间(时间片)内只能运行某个队列的某个task,并经过优先级、FIFO等策略进行task的切换运行。
GCD共提供三种队列形式:
1. main,即主线程,iOS的UI绘制、交互响应都要在此线程上执行
2. concurrent,并发线程队列,task的进出队列,都遵循FIFO策略,但队列中的task‘看起来’是并发执行的完成时间却多是以任意的顺序结束。很容易理解,由于每一个task的执行时间长短一般不同。
3. serial,串行队列,在此队列中的task,one by one的执行,严格遵照FIFO即,咱们要执行一个block(task)
17.描述一下iOS SDK中如何实现MVC的开发模式
MVC是模型、试图、控制开发模式,对于iOS SDK,全部的View都是视图层的,它应该独立于模型层,由视图控制层来控制。全部的用户数据都是模型层,它应该独立于视图。全部的ViewController都是控制层,由它负责控制视图,访问模型数据。
18. 浅复制和深复制的区别?
答案:浅层复制:只复制指向对象的指针,而不复制引用对象自己。
深层复制:复制引用对象自己。
意思就是说我有个A对象,复制一份后获得A_copy对象后,对于浅复制来讲,A和A_copy指向的是同一个内存资源,复制的只不过是是一个指针,对象自己资源
仍是只有一份,那若是咱们对A_copy执行了修改操做,那么发现A引用的对象一样被修改,这其实违背了咱们复制拷贝的一个思想。深复制就好理解了,内存中存在了
两份独立对象自己。
用网上一哥们通俗的话将就是:
浅复制比如你和你的影子,你完蛋,你的影子也完蛋
深复制比如你和你的克隆人,你完蛋,你的克隆人还活着。
19. 类别的做用?继承和类别在实现中有何区别?
答案:category 能够在不获悉,不改变原来代码的状况下往里面添加新的方法,只能添加,不能删除修改。而且若是类别和原来类中的方法产生名称冲突,则类别将覆盖原来的方法,由于类别具备更高的优先级。
类别主要有3个做用:
(1)将类的实现分散到多个不一样文件或多个不一样框架中。
(2)建立对私有方法的前向引用。
(3)向对象添加非正式协议。
继承能够增长,修改或者删除方法,而且能够增长属性。
20. 类别和类扩展的区别。
答案:category和extensions的不一样在于 后者能够添加属性。另外后者添加的方法是必需要实现的。
extensions能够认为是一个私有的Category。
21. oc中的协议和java中的接口概念有何不一样?
答案:OC中的代理有2层含义,官方定义为 formal和informal protocol。前者和Java接口同样。informal protocol中的方法属于设计模式考虑范畴,不是必须实现的,可是若是有实现,就会改变类的属性。
其实关于正式协议,类别和非正式协议我很早前学习的时候大体看过,也写在了学习教程里
“非正式协议概念其实就是类别的另外一种表达方式“这里有一些你可能但愿实现的方法,你能够使用他们更好的完成工做”。
这个意思是,这些是可选的。好比我门要一个更好的方法,咱们就会申明一个这样的类别去实现。而后你在后期能够直接使用这些更好的方法。
这么看,总以为类别这玩意儿有点像协议的可选协议。
如今来看,其实protocal已经开始对二者都统一和规范起来操做,由于资料中说“非正式协议使用interface修饰“,
如今咱们看到协议中两个修饰词:“必须实现(@requied)”和“可选实现(@optional)”。
22. 什么是KVO和KVC?
答案:kvc:键 – 值编码是一种间接访问对象的属性使用字符串来标识属性,而不是经过调用存取方法,直接或经过实例变量访问的机制。
不少状况下能够简化程序代码。apple文档其实给了一个很好的例子。
kvo:键值观察机制,他提供了观察某一属性变化的方法,极大的简化了代码。
具体用看到嗯哼用到过的一个地方是对于按钮点击变化状态的的监控。
好比我自定义的一个button
[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查找的逻辑理解,就说的过去了。
23. 代理的做用?
答案:代理的目的是改变或传递控制链。容许一个类在某些特定时刻通知到其余类,而不须要获取到那些类的指针。能够减小框架复杂度。
另一点,代理能够理解为java中的回调监听机制的一种相似。
24. oc中可修改和不能够修改类型。
答案:可修改不可修改的集合类。这个我我的简单理解就是可动态添加修改和不可动态添加修改同样。
好比NSArray和NSMutableArray。前者在初始化后的内存控件就是固定不可变的,后者能够添加等,能够动态申请新的内存空间。
25. 咱们说的oc是动态运行时语言是什么意思?
答案:多态。 主要是将数据类型的肯定由编译时,推迟到了运行时。
这个问题其实浅涉及到两个概念,运行时和多态。
简单来讲,运行时机制使咱们直到运行时才去决定一个对象的类别,以及调用该类别对象指定方法。
多态:不一样对象以本身的方式响应相同的消息的能力叫作多态。意思就是假设生物类(life)都用有一个相同的方法-eat;
那人类属于生物,猪也属于生物,都继承了life后,实现各自的eat,可是调用是咱们只需调用各自的eat方法。
也就是不一样的对象以本身的方式响应了相同的消息(响应了eat这个选择器)。
所以也能够说,运行时机制是多态的基础?~~~
26. 通知和协议的不一样之处?
答案:协议有控制链(has-a)的关系,通知没有。
首先我一开始也不太明白,什么叫控制链(专业术语了~)。可是简单分析下通知和代理的行为模式,咱们大体能够有本身的理解
简单来讲,通知的话,它能够一对多,一条消息能够发送给多个消息接受者。
代理按咱们的理解,到不是直接说不能一对多,好比咱们知道的明星经济代理人,不少时候一个经济人负责好几个明星的事务。
只是对于不一样明星间,代理的事物对象都是不同的,一一对应,不可能说明天要处理A明星要一个发布会,代理人发出处理发布会的消息后,别称B的
发布会了。可是通知就不同,他只关心发出通知,而不关心多少接收到感兴趣要处理。
所以控制链(has-a从英语单词大体能够看出,单一拥有和可控制的对应关系。
27. 是推送消息?
首先是应用程序注册消息推送。
IOS跟APNS Server要deviceToken。应用程序接受deviceToken。
应用程序将deviceToken发送给PUSH服务端程序。
服务端程序向APNS服务发送消息。
APNS服务将消息发送给iPhone应用程序
28. 关于多态性
答案:多态,子类指针能够赋值给父类。
这个题目其实能够出到一切面向对象语言中,
所以关于多态,继承和封装基本最好都有个自我意识的理解,也并不是必定要把书上资料上写的能背出来。最重要的是转化成自我理解。
29. 对于单例的理解
答案:11,12题目其实出的有点泛泛的感受了,可能说是编程语言须要或是必备的基础。
基本能用熟悉的语言写出一个单例,以及能够运用到的场景或是你编程中碰到过运用的此种模式的框架类等。
进一步点,考虑下如何在多线程访问单例时的安全性。
30. 说说响应链
答案: 事件响应链。包括点击事件,画面刷新事件等。在视图栈内从上至下,或者从下之上传播。能够说点事件的分发,传递以及处理。具体能够去看下touch事件这块。由于问的太抽象化了严重怀疑题目出到越后面就越笼统。能够从责任链模式,来说经过事件响应链处理,其拥有的扩展性
31. frame和bounds有什么不一样?
答案:frame指的是:该view在父view坐标系统中的位置和大小。(参照点是父亲的坐标系统)
bounds指的是:该view在自己坐标系统中 的位置和大小。(参照点是自己坐标系统)
32. 方法和选择器有何不一样?
答案:selector是一个方法的名字,method是一个组合体,包含了名字和实现.
详情能够看apple文档。
33. OC的垃圾回收机制?
答案: OC2.0有Garbage collection,可是iOS平台不提供。
通常咱们了解的objective-c对于内存管理都是手动操做的,可是也有自动释放池。
可是差了大部分资料,貌似不要和arc机制搞混就行了。
34. NSOperation queue?
答案:存放NSOperation的集合类。
操做和操做队列,基本能够当作java中的线程和线程池的概念。用于处理ios多线程开发的问题。网上部分资料提到一点是,虽然是queue,可是却并非带有队列的概念,放入的操做并不是是按照严格的先进现出。这边又有个疑点是,对于队列来讲,先进先出的概念是Afunc添加进队列,Bfunc紧跟着也进入队列,Afunc先执行这个是必然的,可是Bfunc是等Afunc彻底操做完之后,B才开始启动而且执行,所以队列的概念离乱上有点违背了多线程处理这个概念。可是转念一想其实能够参考银行的取票和叫号系统。
所以对于A比B先排队取票可是B率先执行完操做,咱们亦然能够感性认为这仍是一个队列。
可是后来看到一票关于这操做队列话题的文章,其中有一句提到
“由于两个操做提交的时间间隔很近,线程池中的线程,谁先启动是不定的。”瞬间以为这个queue名字有点忽悠人了,还不如pool综合一点,咱们知道他能够比较大的用处在于能够帮组多线程编程就行了。
35. 什么是延迟加载?
答案:懒汉模式,只在用到的时候才去初始化。
也能够理解成延时加载。
我以为最好也最简单的一个列子就是tableView中图片的加载显示了。
一个延时载,避免内存太高,一个异步加载,避免线程堵塞。
36. 是否在一个视图控制器中嵌入两个tableview控制器?
答案:一个视图控制只提供了一个View视图,理论上一个tableViewController也不能放吧,只能说能够嵌入一个tableview视图。固然,题目自己也有歧义,若是不是咱们定性思惟认为的UIViewController,而是宏观的表示视图控制者,那咱们却是能够把其当作一个视图控制者,它能够控制多个视图控制器,好比TabbarController那样的感受。
37. 一个tableView是否能够关联两个不一样的数据源?你会怎么处理?
答案:首先咱们从代码来看,数据源如何关联上的,实际上是在数据源关联的代理方法里实现的。所以咱们并不关心如何去关联他,他怎么关联上,方法只是让我返回根据本身的须要去设置如相关的数据源。所以,我以为能够设置多个数据源啊,可是有个问题是,你这是想干吗呢?想让列表如何显示,不一样的数据源分区块显示?
38. 何时使用NSMutableArray,何时使用NSArray?
答案:当数组在程序运行时,须要不断变化的,使用NSMutableArray,当数组在初始化后,便再也不改变的,使用NSArray。须要指出的是,使用NSArray只代表的是该数组在运行时不发生改变,即不能往NSAarry的数组里新增和删除元素,但不代表其数组內的元素的内容不能发生改变。NSArray是线程安全的,NSMutableArray不是线程安全的,多线程使用到NSMutableArray须要注意。
39. 给出委托方法的实例,而且说出UITableVIew的Data Source方法
答案:CocoaTouch框架中用到了大量委托,其中UITableViewDelegate就是委托机制的典型应用,是一个典型的使用委托来实现适配器模式,其中UITableViewDelegate协议是目标,tableview是适配器,实现UITableViewDelegate协议,并将自身设置为talbeview的delegate的对象,是被适配器,通常状况下该对象是UITableViewController。
UITableVIew的Data Source方法有- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
40. 在应用中能够建立多少autorelease对象,是否有限制?
答案:无
41. 若是咱们不建立内存池,是否有内存池提供给咱们?
答案:界面线程维护着本身的内存池,用户本身建立的数据线程,则须要建立该线程的内存池
42. 何时须要在程序中建立内存池?
答案:用户本身建立的数据线程,则须要建立该线程的内存池
43. 类NSObject的那些方法常常被使用?
答案:NSObject是Objetive-C的基类,其由NSObject类及一系列协议构成。
其中类方法alloc、class、 description 对象方法init、dealloc、– performSelector:withObject:afterDelay:等常常被使用
44. 什么是简便构造方法?
答案:简便构造方法通常由CocoaTouch框架提供,如NSNumber的 + numberWithBool: + numberWithChar: + numberWithDouble: + numberWithFloat: + numberWithInt:
Foundation下大部分类均有简便构造方法,咱们能够经过简便构造方法,得到系统给咱们建立好的对象,而且不须要手动释放。
45. 如何使用Xcode设计通用应用?
答案:使用MVC模式设计应用,其中Model层完成脱离界面,即在Model层,其是可运行在任何设备上,在controller层,根据iPhone与iPad(独有UISplitViewController)的不一样特色选择不一样的viewController对象。在View层,可根据现实要求,来设计,其中以xib文件设计时,其设置其为universal。
46. UIView的动画效果有那些?
答案:有不少,如 UIViewAnimationOptionCurveEaseInOut UIViewAnimationOptionCurveEaseIn UIViewAnimationOptionCurveEaseOut UIViewAnimationOptionTransitionFlipFromLeft UIViewAnimationOptionTransitionFlipFromRight UIViewAnimationOptionTransitionCurlUpUIViewAnimationOptionTransitionCurlDown
47. 在iPhone应用中如何保存数据?
答案:有如下几种保存机制:
1.经过web服务,保存在服务器上
2.经过NSCoder固化机制,将对象保存在文件中
3.经过SQlite或CoreData保存在文件数据库中
48. 什么是coredata?
答案:coredata是苹果提供一套数据保存框架,其基于SQlite
49. 什么是NSManagedObject模型?
答案:NSManagedObject是NSObject的子类 ,也是coredata的重要组成部分,它是一个通用的类,实现了core data 模型层所需的基本功能,用户可经过子类化NSManagedObject,创建本身的数据模型。
50. 什么是NSManagedobjectContext?
答案:NSManagedobjectContext对象负责应用和数据库之间的交互。
51. 什么是谓词?
答案:谓词是经过NSPredicate,是经过给定的逻辑条件做为约束条件,完成对数据的筛选。
predicate = [NSPredicate predicateWithFormat:@"customerID == %d",n];
a = [customers filteredArrayUsingPredicate:predicate];
52. 和coredata一块儿有哪几种持久化存储机制?
答案:存入到文件、 存入到NSUserDefaults(系统plist文件中)、存入到Sqlite文件数据库
53. 谈谈对Block 的理解?并写出一个使用Block执行UIVew动画?
答案:Block是能够获取其余函数局部变量的匿名函数,其不但方便开发,而且能够大幅提升应用的执行效率(多核心CPU可直接处理Block指令)
[UIView transitionWithView:self.view
duration:0.2
options:UIViewAnimationOptionTransitionFlipFromLeft
animations:^{ [[blueViewController view] removeFromSuperview]; [[self view] insertSubview:yellowViewController.view atIndex:0]; }
completion:NULL];
54. 写出上面代码的Block的定义。
答案:
typedef void(^animations) (void);
typedef void(^completion) (BOOL finished);
55. 试着使用+ beginAnimations:context:以及上述Block的定义,写出一个能够完成
+ (void)transitionWithView:(UIView *)view duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion NS_AVAILABLE_IOS(4_0);操做的函数执行部分
答案:无
网络部分
56. 作过的项目是否涉及网络访问功能,使用什么对象完成网络功能?
答案:ASIHTTPRequest与NSURLConnection
57. 简单介绍下NSURLConnection类及+ sendSynchronousRequest:returningResponse:error:与– initWithRequest:delegate:两个方法的区别?
答案: NSURLConnection主要用于网络访问,其中+ sendSynchronousRequest:returningResponse:error:是同步访问数据,即当前线程会阻塞,并等待request的返回的response,而– initWithRequest:delegate:使用的是异步加载,当其完成网络访问后,会经过delegate回到主线程,并其委托的对象。
58. 多线程是什么
多线程是个复杂的概念,按字面意思是同步完成多项任务,提升了资源的使用效率,从硬件、操做系统、应用软件不一样的角度去看,多线程被赋予不一样的内涵,对于硬件,如今市面上多数的CPU都是多核的,多核的CPU运算多线程更为出色;从操做系统角度,是多任务,如今用的主流操做系统都是多任务的,能够一边听歌、一边写博客;对于应用来讲,多线程可让应用有更快的回应,能够在网络下载时,同时响应用户的触摸操做。在iOS应用中,对多线程最初的理解,就是并发,它的含义是原来先作烧水,再摘菜,再炒菜的工做,会变成烧水的同时去摘菜,最后去炒菜。
59. iOS 中的多线程
iOS中的多线程,是Cocoa框架下的多线程,经过Cocoa的封装,可让咱们更为方便的使用线程,作过C++的同窗可能会对线程有更多的理解,好比线程的创立,信号量、共享变量有认识,Cocoa框架下会方便不少,它对线程作了封装,有些封装,可让咱们建立的对象,自己便拥有线程,也就是线程的对象化抽象,从而减小咱们的工程,提供程序的健壮性。
GCD是(Grand Central Dispatch)的缩写 ,从系统级别提供的一个易用地多线程类库,具备运行时的特色,能充分利用多核心硬件。GCD的API接口为C语言的函数,函数参数中多数有Block,关于Block的使用参看这里,为咱们提供强大的“接口”,对于GCD的使用参见本文
NSOperation与Queue
NSOperation是一个抽象类,它封装了线程的细节实现,咱们能够经过子类化该对象,加上NSQueue来同面向对象的思惟,管理多线程程序。具体可参看这里:一个基于NSOperation的多线程网络访问的项目。
NSThread
NSThread是一个控制线程执行的对象,它不如NSOperation抽象,经过它咱们能够方便的获得一个线程,并控制它。但NSThread的线程之间的并发控制,是须要咱们本身来控制的,能够经过NSCondition实现。
参看 iOS多线程编程之NSThread的使用
其余多线程
在Cocoa的框架下,通知、Timer和异步函数等都有使用多线程,(待补充).
60. 在项目何时选择使用GCD,何时选择NSOperation?
项目中使用NSOperation的优势是NSOperation是对线程的高度抽象,在项目中使用它,会使项目的程序结构更好,子类化NSOperation的设计思路,是具备面向对象的优势(复用、封装),使得实现是多线程支持,而接口简单,建议在复杂项目中使用。
项目中使用GCD的优势是GCD自己很是简单、易用,对于不复杂的多线程操做,会节省代码量,而Block参数的使用,会是代码更为易读,建议在简单项目中使用。
61. 什么是block
对于闭包(block),有不少定义,其中闭包就是可以读取其它函数内部变量的函数,这个定义即接近本质又较好理解。对于刚接触Block的同窗,会以为有些绕,由于咱们习惯写这样的程序main(){ funA();} funA(){funB();} funB(){…..}; 就是函数main调用函数A,函数A调用函数B… 函数们依次顺序执行,但现实中不全是这样的,例如项目经理M,手下有3个程序员A、B、C,当他给程序员A安排实现功能F1时,他并不等着A完成以后,再去安排B去实现F2,而是安排给A功能F1,B功能F2,C功能F3,而后可能去写技术文档,而当A遇到问题时,他会来找项目经理M,当B作完时,会通知M,这就是一个异步执行的例子。在这种情形下,Block即可大显身手,由于在项目经理M,给A安排工做时,同时会告诉A若果遇到困难,如何能找到他报告问题(例如打他手机号),这就是项目经理M给A的一个回调接口,要回掉的操做,好比接到电话,百度查询后,返回网页内容给A,这就是一个Block,在M交待工做时,已经定义好,而且取得了F1的任务号(局部变量),倒是在当A遇到问题时,才调用执行,跨函数在项目经理M查询百度,得到结果后回调该block。
62. block 实现原理
Objective-C是对C语言的扩展,block的实现是基于指针和函数指针。
从计算语言的发展,最先的goto,高级语言的指针,到面向对象语言的block,从机器的思惟,一步步接近人的思惟,以方便开发人员更为高效、直接的描述出现实的逻辑(需求)。
下面是两篇很好的介绍block实现的博文
iOS中block实现的探究
谈Objective-C Block的实现
block的使用
使用实例
cocoaTouch框架下动画效果的Block的调用
使用typed声明block
typedef void(^didFinishBlock) (NSObject *ob);
这就声明了一个didFinishBlock类型的block,
而后即可用
@property (nonatomic,copy) didFinishBlock finishBlock;
声明一个blokc对象,注意对象属性设置为copy,接到block 参数时,便会自动复制一份。
block是一种特殊类型,
使用该关键字声明的局部变量,能够被block所改变,而且其在原函数中的值会被改变。
常见系列面试题
面试时,面试官会先问一些,是否了解block,是否使用过block,这些问题至关于开场白,每每是下面一系列问题的开始,因此必定要如实根据本身的状况回答。
1 使用block和使用delegate完成委托模式有什么优势?
首先要了解什么是委托模式,委托模式在iOS中大量应用,其在设计模式中是适配器模式中的对象适配器,Objective-C中使用id类型指向一切对象,使委托模式更为简洁。了解委托模式的细节:
iOS设计模式—-委托模式
使用block实现委托模式,其优势是回调的block代码块定义在委托对象函数内部,使代码更为紧凑;
适配对象再也不须要实现具体某个protocol,代码更为简洁。
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();});
63.委托是什么?委托和委托方双方的property声明用什么属性?为何?
委托:一个对象保存另一个对象的引用,被引用的对象实现了事先肯定的协议,该协议用于将引用对象中的变化通知给被引用对象。
委托和委托方双方的property声明属性都是assign而不是retain
为了不循环引用形成的内存泄露。
64.循环引用的问题这样理解:
好比在main函数中建立了两个类的对象A和B,如今引用计数都是1。如今让A和B互相引用(A有一个属性是B对象,属性说明是retain;B有一个属性是A对象,属性说明是retain),如今两个对象的引用计数都增长了1,都变成了2。
如今执行[A release]; [B release]; 此时建立对象的main函数已经释放了本身对对象的全部权,可是此时A和B的引用计数都仍是1,由于他们互相引用了。
这时你发现A和B将没法释放,由于要想释放A必须先释放B,在B的dealloc方法中再释放A。同理,要想释放B必须先释放A,在A的dealloc方法中再释放B。因此这两个对象将一直存在在内存中而不释放。这就是所谓的循环引用的问题。要想解决这个问题,通常的方法能够将引用的属性设置为assign,而不是retain来处理。
65.延展是什么?做用是什么?
答:延展(extension):在本身类的实现文件中添加类目来声明私有方法。
延展(Extension)“匿名”的类目,延展定义类的私有方法,通常是在类的实现文件@implementation之上定义如:Person() 和类目的区别在于括号里面是空的,没有名字的,暂时性的存在,只能本类调用方法,子类也没法调用父类的延展
另外在本类的实现文件@implementation之上也能够定义私有方法,私有的静态变量
延展的特色就是定义私有方法
66.内存管理的几条原则是什么?按照默认法则,哪些关键字生成的对象须要手动释放?哪些状况下不须要手动释放,会直接进入自动释放池?
当使用new、alloc或copy方法建立一个对象时,该对象引用计数器为1。若是不须要使用该对象,能够向其发送release或autorelease消息,在其使用完毕时被销毁。
若是经过其余方法获取一个对象,则能够假设这个对象引用计数为1,而且被设置为autorelease,不须要对该对象进行清理,若是确实须要retain这个对象,则须要使用完毕后release。
若是retain了某个对象,须要release或autorelease该对象,保持retain方法和release方法使用次数相等。
使用new、alloc、copy关键字生成的对象和retain了的对象须要手动释放。设置为autorelease的对象不须要手动释放,会直接进入自动释放池。
67.怎样实现一个单例模式的类,给出思路,不写代码。
首先必须建立一个全局实例,一般存放在一个全局变量中,此全局变量设置为nil
提供工厂方法对该全局实例进行访问,检查该变量是否为nil,若是nil就建立一个新的实例,最后返回全局实例
全局变量的初始化在第一次调用工厂方法时会在+allocWithZone:中进行,因此须要重写该方法,防止经过标准的alloc方式建立新的实例
为了防止经过copy方法获得新的实例,须要实现-copyWithZone方法
只需在此方法中返回自己对象便可,引用计数也不须要进行改变,由于单例模式下的对象是不容许销毁的,因此也就不用保留
由于全局实例不容许释放,因此retain,release,autorelease方法均需重写
68.@class的做用是什么?
答:在头文件中, 通常只须要知道被引用的类的名称就能够了。 不须要知道其内部的实体变量和方法,因此在头文件中通常使用@class来声明这个名称是类的名称。 而在实现类里面,由于会用到这个引用类的内部的实体变量和方法,因此须要使用#import来包含这个被引用类的头文件。
@class的做用是告诉编译器,有这么一个类,用吧,没有问题
@class还能够解决循环依赖的问题,例如A.h导入了B.h,而B.h导入了A.h,每个头文件的编译都要让对象先编译成功才行
使用@class就能够避免这种状况的发生
69.KVC是什么?KVO是什么?有什么特色?
KVC是键值编码,特色是经过指定表示要访问的属性名字的字符串标识符,能够进行类的属性读取和设置
KVO是键值观察,特色是利用键值观察能够注册成为一个对象的观察者,在该对象的某个属性变化时收到通知
70.MVC是什么?有什么特性?
MVC是一种设计模式,由模型、视图、控制器3部分组成。
模型:保存应用程序数据的类,处理业务逻辑的类
视图:窗口,控件和其余用户能看到的而且能交互的元素
控制器:将模型和试图绑定在一块儿,肯定如何处理用户输入的类
71.定义属性时,什么状况使用copy、assign、retain?
使用assign: 对基础数据类型 (NSInteger,CGFloat)和C数据类型(int, float,double, char, 等等)
使用copy: 但愿得到源对象的副本而不改变源对象内容时,对NSString
使用retain: 但愿得到源对象的全部权时,对其余NSObject和其子类
72.属性readwrite,readonly,assign,retain,copy,nonatomic 各是什么做用,在那种状况下用?
assign用于简单数据类型,如NSInteger,double,bool,
retain和copy用于对象,
readwrite是可读可写特性;须要生成getter方法和setter方法时readonly是只读特性 只会生成getter方法 不会生成setter方法 ;不但愿属性在类外改变.
assign是赋值特性,setter方法将传入参数赋值给实例变量;仅设置变量时;
retain表示持有特性,setter方法将传入参数先保留,再赋值,传入参数的retaincount会+1;copy表示赋值特性,setter方法将传入对象复制一份;须要彻底一份新的变量时。
nonatomic非原子操做,决定编译器生成的setter getter是不是原子操做,atomic表示多线程安全,通常使用nonatomic
73.id 声明的对象有什么特性?
答:Id声明的对象具备运行时的特性,便可以指向任意类型的objcetive-c的对象;
74.iPhone5 的屏幕分辨率大小为 1136* 640 ?
答:屏幕分辨率:用于量度位图图像内数据量多少的一个参数。一般表示成ppi(每英寸像素Pixel per inch)。屏幕物理尺寸不变,分辨率越高,每单位面积内包含的细节(像素点)越多。
75.struct strA { int a; float b; char c; } expA;
printf("%ld",sizeof(expA)); 输出结果为 12 ?
该问题涉及编译器的“内存对齐”问题:
现代计算机中内存空间都是按照byte(字节)划分的,从理论上讲彷佛对任何类型的变量的访问能够从任何地址开始,但实际状况是在访问特定变量的时候常常在特定的内存地址访问,这就须要各种型数据按照必定的规则在空间上排列,而不是顺序的一个接一个的排放,这就是对齐。
对齐的做用和缘由:各个硬件平台对存储空间的处理上有很大的不一样。一些平台对某些特定类型的数据只能从某些特定地址开始存取。其余平台可能没有这种状况, 可是最多见的是若是不按照适合其平台的要求对数据存放进行对齐,会在存取效率上带来损失。好比有些平台每次读都是从偶地址开始,若是一个int型(假设为 32位)若是存放在偶地址开始的地方,那么一个读周期就能够读出,而若是存放在奇地址开始的地方,就可能会须要2个读周期,并对两次读出的结果的高低 字节进行拼凑才能获得该int数据。显然在读取效率上降低不少。这也是空间和时间的博弈。
一般,咱们写程序的时候,不须要考虑对齐问题。编译器会替咱们选择适合目标平台的对齐策略。固然,咱们也能够通知给编译器传递预编译指令而改变对指定数据的对齐方法。
可是,正由于咱们通常不须要关心这个问题,因此由于编辑器对数据存放作了对齐,而咱们不了解的话,经常会对一些问题感到迷惑。最多见的就是struct数据结构的sizeof结果,出乎意料。
对于结构体来讲,按成员中所占字节最大的是float类型,占用4个字节,一共有3个成员,因此总的占用字节为:4* 3 = 12.
可经过编译器命令来设定:
#progma pack (2)
76.OSI(Open System Interconnection)开放式系统互联参考模型 把网络协议从逻辑上分为了7层,试列举常见的应用层协议。
注意问的是应用层协议,有些同窗直接答了七层模型。
在开放系统互连(OSI)模型中的最高层,为应用程序提供服务以保证通讯,但不是进行通讯的应用程序自己。
Telnet协议是TCP/IP协议族中的一员,是Internet远程登录服务的标准协议和主要方式。它为用户提供了在本地计算机上完成远程主机工做的能力。
FTP文件传输协议是TCP/IP网络上两台计算机传送文件的协议,FTP是在TCP/IP网络和INTERNET上最先使用的协议之一,它属于网络协议组的应用层。
超文本传输协议 (HTTP-Hypertext transfer protocol) 是分布式,协做式,超媒体系统应用之间的通讯协议。是万维网(world wide web)交换信息的基础。
SMTP(Simple MailTransfer Protocol)即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式,它帮助每台计算机在发送或中转信件时找到下一个目的地。
时间协议(TIME protocol)是一个在RFC 868内定义的网络协议。它用做提供机器可读的日期时间资讯。
DNS 是域名系统 (Domain NameSystem) 的缩写,是因特网的一项核心服务,它做为能够将域名和IP地址相互映射的一个分布式数据库。
SNMP(Simple Network ManagementProtocol,简单网络管理协议)的前身是简单网关监控协议(SGMP),用来对通讯线路进行管理。
TFTP(Trivial FileTransfer Protocol,简单文件传输协议)是TCP/IP协议族中的一个用来在客户机与服务器之间进行简单文件传输的协议,提供不复杂、开销不大的文件传输服务。端口号为69。
77.网络传输层协议中,基于TCP/IP协议和UDP/IP的链接有什么区别?
TCP:TransmissionControl Protocol 传输控制协议TCP是一种面向链接(链接导向)的、可靠的、基于字节流的运输层(Transport layer)通讯协议,由IETF的RFC 793说明(specified)。
UDP 是User DatagramProtocol的简称, 中文名是用户数据包协议,是OSI 参考模型中一种无链接的传输层协议,提供面向事务的简单不可靠信息传送服务,IETF RFC 768是UDP的正式规范。
面向链接:是指通讯双方在通讯时,要事先创建一条通讯线路,其有三个过程:创建链接、使用链接和释放链接。电话系统是一个面向链接的模式,拨号、通话、挂机;TCP协议就是一种面向链接的协议。
面向无链接:是指通讯双方不须要事先创建一条通讯线路,而是把每一个带有目的地址的包(报文分组)送到线路上,由系统自主选定路线进行传输。邮政系统是一个无链接的模式,天罗地网式的选择路线,天女散花式的传播形式;IP、UDP协议就是一种无链接协议。
78.简述MVC模式中M、V、C分别指代什么及发挥的做用?
MVC开始是存在于Desktop(桌面)程序中的,M是指数据模型,V是指用户界面,C则是控制器,使用MVC的目的是将M和V的实现代码分离。C存在的目的则是确保M和V的同步,一旦M改变,V应该同步更新。
视图是用户看到并与之交互的界面,视图没有真正的处理发生,无论这些数据是联机存储的仍是一个雇员列表,做为视图来说,它只是做为一种输出数据并容许用户操纵的方式。
模型表示企业数据和业务规则,模型返回的数据是中立的,就是说模型与数据格式无关,这样一个模型能为多个视图提供数据,因为应用于模型的代码只需写一次就能够被多个视图重用,因此减小了代码的重复性。
控制器接受用户的输入并调用模型和视图去完成用户的需求,控制器自己不输出任何东西和作任何处理。它只是接收请求并决定调用哪一个模型构件去处理请求,而后再肯定用哪一个视图来显示返回的数据。
79.声明@property的语法中,retain、copy、assign的含义及做用?试写出 @property中带retain和assign关键字,经过@synthesize自动生成的的合成存取方法(set、get方法)的实现代码。
getter分析:
@property (nonatomic, retain) test*aTest;
@property (nonatomic, copy) test*aTest;
等效代码:
-(void)aTest {
return aTest;
}
@property (retain) test* aTest;
@property (copy) test* aTest;
等效代码:
-(void)aTest
{
[aTest retain];
return [aTest autorelease];
}
setter分析:
@property (nonatomic, retain) test*aTest;
@property (retain) test* aTest;
等效于:
-(void)setaTest:(test *)newaTest {
if (aTest !=newaTest) {
[aTest release];
aTest = [newaTest retain];
}
}
@property (nonatomic, copy) test*aTest;
@property (copy) test* aTest;
等效于:
-(void)setaTest:(test *)newaTest {
if (aTest != newaTest){
[aTest release];
aTest = [newaTest copy];
}
}
80.iOS中有哪些回调机制,并做简单的比较。
各类回调机制的比较:
1)目标动做对:当两个对象之间有比较紧密的关系时,如视图控制器与其下的某个视图。
2)代理:也叫委托,当某个对象收到多个事件,并要求同一个对象来处理全部事件时。委托机制依赖于某个协议定义的方法来发送消息。
3)通告机制:当须要多个对象或两个无关对象处理同一个事件时。
4)Block:适用于回调只发生一次的简单任务。
81.列出在编码中哪些编码习惯有助于提升代码质量、软件性能和健壮性,减小程序崩溃。
使用严格的命名规则(如匈牙利命名法)可以避免没必要要的类型转换错误。
在编码前先设计好流程图或使用伪代码,清晰化整个设计意图。
对本身的代码进行严格的单元测试(unit testing)。
单元测试是指对软件中的最小可测试单元进行检查和验证。如C语言中单元指一个函数,Java里单元指一个类,图形化的软件中能够指一个窗口或一个菜单等。总的来讲,单元就是人为规定的最小的被测功能模块。单元测试是在软件开发过程当中要进行的最低级别的测试活动,软件的独立单元将在与程序的其余部分相隔离的状况下进行测试。
异常的处理
首先不要轻易使用异常的捕获,其次要尽量捕获具体的异常。对于异常的处理最好可以采用封装的方式,你们统一使用。这样能够保证异常处理的一致性也能够保证当异常出现时性能的稳定。
使用内省的方法检查方法的输入
采用增量式的编程方式。
采用增量式编程和测试,会倾向于建立更小的方法和更具内聚性的类。你应该常常评估代码质量,并不时的进行许多小调整,而不是一次修改许多东西。在写了几行代码以后,就应该进行一次构建/测试。在没有获得反馈时,你不要走的太远。
#使用工具(如Instrument)来帮助检查内存泄漏、过早释放内存、CPU使用效率等问题。
#消除全部的编译警告,警告就是错误。
#写防护性的代码,使用内省的方法检查传入的参数。
82.JSON中{ }表明_____,[ ]表明_____,试将下面的JSON串用OC对象表示出来:
{ "people": [
{ "firstName": "Brett","lastName":"McLaughlin", "email":"aaaa" },
{ "firstName": "Jason","lastName":"Hunter", "email": "bbbb"},
{ "firstName": "Elliotte","lastName":"Harold", "email": "cccc" }
],
“location”:”中华人民共和国”
}
JSON中{ }表明对象,数据结构为{key1:value1, key2:value2, key3:…… }
[ ]表明数组,与其余语言中的数组相似。
//
@interface People: NSObject
@property(nonatomic, copy) NSString* strFirstName;
@property(nonatomic, copy) NSString* strLastName;
@property(nonatomic, copy) NSString* strEmail;
@end
//
@interfaceJSonData : NSObject
@property(nonatomic, retain) NSMutableArray* arrPeople; // 存放People对象
@property(nonatomic, copy) NSString* strLocation;
@end
83.bject-C有私有方法吗?私有变量呢?
objective-c – 类里面的方法只有两种, 静态方法和实例方法.
在类里面声名一个私有方法?@interface Controller : NSObject
{ NSString *something;
}?+ (void)thisIsAStaticMethod;?–(void)thisIsAnInstanceMethod;?@end?@interface Controller
(private)
-(void)thisIsAPrivateMethod;?@end
@private能够用来修饰私有变量?在Objective‐C中,全部实例变量默认都是私有的,全部实例方法默认都是公有的
84. 堆和栈的区别?
管理方式:对于栈来说,是由编译器自动管理,无需咱们手工控制;对于堆来讲,释放工做由程序员控制,容易产生memory leak。
申请大小:栈:栈是向低地址扩展的数据结构,是一块连续的内存的区域
堆:是向高地址扩展的数据结构,是不连续的内存区域。
分配方式:堆都是动态分配的 ,动态分配由alloca函数进行分配
栈的动态分配由编译器进行释放,无需咱们手工实现
85. kvc和kvo的区别?
kvc:键值编码,是一种间接访问对象的属性,使用字符串来标示属性
kvo:键值观察机制,提供了观察某一属性变化的方法
86. 类别的做用?
答:有时咱们须要在一个已经定义好的类中增长一些方法,而不想去重写该类。能够使用类别对该类扩充新的方法。
注意:类别只能扩充方法,而不能扩充成员变量。
代理的做用
委托代理(degegate),目的是改变和传递控制链
顾名思义,把某个对象要作的事情委托给别的对象去作。那么别的对象就是这个对象的代理,代替它来打理要作的事。反映到程序中,首先要明确一个对象的委托方是哪一个对象,委托所作的内容是什么。
委托机制是一种设计模式。
多态:子类的指针能够赋值给父类
87.链表和数组的区别在哪里?
两者都属于一种数据结构
从逻辑结构来看
1. 数组必须事先定义固定的长度(元素个数),不能适应数据动态地增减的状况。当数据增长时,可能超出原先定义的元素个数;当数据减小时,形成内存浪费;数组能够根据下标直接存取。
2. 链表动态地进行存储分配,能够适应数据动态地增减的状况,且能够方便地插入、删除数据项。(数组中插入、删除数据项时,须要移动其它数据项,很是繁琐)链表必须根据next指针找到下一个元素
从内存存储来看
1. (静态)数组从栈中分配空间, 对于程序员方便快速,可是自由度小
2. 链表从堆中分配空间, 自由度大可是申请管理比较麻烦
从上面的比较能够看出,若是须要快速访问数据,不多或不插入和删除元素,就应该用数组;相反, 若是须要常常插入和删除元素就须要用链表数据结构了。
88.. 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].
89. 写一个委托的interface
@protocol MyDelegate;
@interface MyClass: NSObject
{ id <MyDelegate> delegate; }
//委托方法@protocol MyDelegate- (void)didJobs:(NSArray *)args;
@end
90. 写一个NSString类的实现
+(id)initWithCString:(const char *)nullTerminatedCStringencoding:(NSStringEncoding)encoding;
+ (id)stringWithCString: (const char*)nullTerminatedCString
ncoding: (NSStringEncoding)encoding
{ NSString *obj;
obj = [selfallocWithZone: NSDefaultMallocZone()];
obj = [objinitWithCString: nullTerminatedCString encoding: encoding];
returnAUTORELEASE(obj);
}
91. 关键字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)
多线程应用中被几个任务共享的变量
92.一个参数既能够是const还能够是volatile吗?解释为何。 一个指针能够是volatile 吗?解释为何。
答案:
是的。一个例子是只读的状态寄存器。它是volatile由于它可能被意想不到地改变。它是const由于程序不该该试图去修改它。
是的。尽管这并不很常见。一个例子是当一个中服务子程序修该一个指向一个buffer的指针时。
93.static关键字的做用:
(1)函数体内 static 变量的做用范围为该函数体,不一样于 auto 变量,该变量的内存只被分配一次,所以其值在下次调用时仍维持上次的值; (2)在模块内的 static 全局变量能够被模块内所用函数访问,但不能被模块外其它函数访问;
(3)在模块内的 static 函数只可被这一模块内的其它函数调用,这个函数的使用范围被限制在声明 它的模块内;
(4)在类中的 static 成员变量属于整个类所拥有,对类的全部对象只有一份拷贝;
(5)在类中的 static 成员函数属于整个类所拥有,这个函数不接收 this 指针,于是只能访问类的static 成员变量。
94.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 类型。
95.为何标准头文件都有相似如下的结构?
#ifndef __INCvxWorksh
#define __INCvxWorksh
#ifdef __cplusplus
extern "C" {
#endif /*...*/
#ifdef __cplusplus
}
#endif
#endif /* __INCvxWorksh */
显然,头文件中的编译宏“#ifndef __INCvxWorksh、#define __INCvxWorksh、#endif” 的做用是防止该头文件被重复引用。
96.线程与进程的区别和联系?
答:主要不一样的是操做系统资源管理方式
线程是一个进程中不一样的执行路径,线程有本身的堆、局部变量
进程有独立的地址空间,一个线程死掉,整个进程就会死掉
进程和线程都是由操做系统所体会的程序运行的基本单元,系统利用该基本单元实现系统对应用的并发性。
程和线程的主要差异在于它们是不一样的操做系统资源管理方式。
进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不一样执行路径。
线程有本身的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,因此多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行而且又要共享某些变量的并发操做,只能用线程,不能用进程。
97.列举几种进程的同步机制,并比较其优缺点。
答案:原子操做、信号量机制、自旋锁、管程、会合、分布式系统
进程之间通讯的途径
答案:共享存储系统消息传递系统管道:以文件系统为基础
进程死锁的缘由
答案:资源竞争及进程推动顺序非法
死锁的4个必要条件
答案:互斥、请求保持、不可剥夺、环路
死锁的处理
答案:鸵鸟策略、预防策略、避免策略、检测与解除死锁
98.什么是键-值,键路径是什么
答:模型的性质是经过一个简单的键(一般是个字符串)来指定的。视图和控制器经过键来查找相应的属性值。在一个给定的实体中,同一个属性的全部值具备相同的数据类型。键-值编码技术用于进行这样的查找—它是一种间接访问对象属性的机制。
键路径是一个由用点做分隔符的键组成的字符串,用于指定一个链接在一块儿的对象性质序列。第一个键的性质是由先前的性质决定的,接下来每一个键的值也是相对于其前面的性质。键路径使您能够以独立于模型实现的方式指定相关对象的性质。经过键路径,您能够指定对象图中的一个任意深度的路径,使其指向相关对象的特定属性。
For example, the keypath address.streetwould get the value of the address property from thereceivingobject, and then determine the street property relative to the addressobject.
99.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.
100.目标-动做机制
答:目标是动做消息的接收者。一个控件,或者更为常见的是它的单元,以插座变量(参见"插座变量"部分) 的形式保有其动做消息的目标。
动做是控件发送给目标的消息,或者从目标的角度看,它是目标为了响应动做而实现的方法。程序须要某些机制来进行事件和指令的翻译。这个机制就是目标-动做机制。
101. cocoa touch框架
这些框架包括:
Core Animation
经过Core Animation,您就能够经过一个基于组合独立图层的简单的编程模型来建立丰富的用户体验。
Core Audio
Core Audio是播放,处理和录制音频的专业技术,可以轻松为您的应用程序添增强大的音频功能。
Core Data提供了一个面向对象的数据管理解决方案,它易于使用和理解,甚至可处理任何应用或大或小的数据模型。
功能列表:框架分类
下面是 Cocoa Touch 中一小部分可用的框架:
音频和视频
CoreAudio
OpenAL
MediaLibrary
AVFoundation
数据管理
Core Data
SQLite
图形和动画
CoreAnimation
OpenGL ES
Quartz 2D
网络/li>
Bonjour
WebKit
BSDSockets
用户应用
AddressBook
CoreLocation
MapKit
StoreKit
102.objc的内存管理
答:若是您经过分配和初始化(好比[[MyClass alloc] init])的方式来建立对象,您就拥有这个对象,须要负责该对象的释放。这个规则在使用NSObject的便利方法new 时也一样适用。
若是您拷贝一个对象,您也拥有拷贝获得的对象,须要负责该对象的释放。若是您保持一个对象,您就部分拥有这个对象,须要在再也不使用时释放该对象。反过来,若是您从其它对象那里接收到一个对象,则您不拥有该对象,也不该该释放它(这个规则有少数的例外,在参考文档中有显式的说明)。
103.自动释放池是什么,如何工做?
答:当您向一个对象发送一个autorelease消息时,Cocoa就会将该对象的一个引用放入到最新的自动释放池。它仍然是个正当的对象,所以自动释放池定义的做用域内的其它对象能够向它发送消息。当程序执行到做用域结束的位置时,自动释放池就会被释放,池中的全部对象也就被释放。
1)ojc-c是经过一种"referring counting"(引用计数)的方式来管理内存的, 对象在开始分配内存(alloc)的时候引用计数为一,之后每当碰到有copy,retain的时候引用计数都会加一, 每当碰到release和autorelease的时候引用计数就会减一,若是此对象的计数变为了0, 就会被系统销毁.
2) NSAutoreleasePool就是用来作引用计数的管理工做的,这个东西通常不用你管的.
3)autorelease和release没什么区别,只是引用计数减一的时机不一样而已,autorelease会在对象的使用真正结束的时候才作引用计数减一。
104.类工厂方法是什么?
答:类工厂方法的实现是为了向客户提供方便,它们将分配和初始化合在一个步骤中,返回被建立的对象,并进行自动释放处理。这些方法的形式是+ (type)className...(其中 className不包括任何前缀)。工厂方法可能不只仅为了方便使用。它们不但能够将分配和初始化合在一块儿,还能够为初始化过程提供对象的分配信息。类工厂方法的另外一个目的是使类(好比NSWorkspace)提供单件实例。虽然init...方法能够确认一 个类在每次程序运行过程只存在一个实例,但它须要首先分配一个“生的”实例,而后还必须释放该实例。工厂方法则能够避免为可能没有用的对象盲目分配内存。
105. 单件实例是什么?
Foundation和Application Kit 框架中的一些类只容许建立单件对象,即这些类在当前进程中的惟一实例。举例来讲,NSFileManager和NSWorkspace 类在使用时都是基于进程进行单件对象的实例化。当向这些类请求实例的时候,它们会向您传递单一实例的一个引用,若是该实例还不存在,则首先进行实例的分配和初始化。单件对象充当控制中心的角色,负责指引或协调类的各类服务。若是类在概念上只有一个实例(好比NSWorkspace),就应该产生一个单件实例,而不是多个实例;若是未来某一天可能有多个实例,您能够使用单件实例机制,而不是工厂方法或函数。
106.动态绑定
—在运行时肯定要调用的方法
动态绑定将调用方法的肯定也推迟到运行时。在编译时,方法的调用并不和代码绑定在一块儿,只有在消实发送出来以后,才肯定被调用的代码。经过动态类型和动态绑定技术,您的代码每次执行均可以获得不一样的结果。运行时因子负责肯定消息的接收者和被调用的方法。运行时的消息分发机制为动态绑定提供支持。当您向一个动态类型肯定了的对象发送消息时,运行环境系统会经过接收者的isa指针定位对象的类,并以此为起点肯定被调用的方法,方法和消息是动态绑定的。并且,您没必要在Objective-C 代码中作任何工做,就能够自动获取动态绑定的好处。您在每次发送消息时,特别是当消息的接收者是动态类型已经肯定的对象时,动态绑定就会例行而透明地发生。
107.obj-c的优缺点objc
优势:
1) Cateogies 2) Posing 3) 动态识别 4) 指标计算 5)弹性讯息传递 6) 不是一个过分复杂的 C 衍生语言 7) Objective-C 与 C++ 可混合编程
缺点:
1) 不支援命名空间 2) 不支持运算符重载 3) 不支持多重继承 4) 使用动态运行时类型,全部的方法都是函数调用,因此不少编译时优化方法都用不到。(如内联函数等),性能低劣。
108.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格式化的函数的长度不可控,有可能格式化后的字符串会超出缓冲区的大小,形成溢出。
2、面试题小结
一、协议:至关于一个方法列表,多个类能够共享的方法的列表
代理:它是一个设计模式,本质就是两个对象之间的调用 id的范型
二、MVC设计模式,一个架构级的思路,这个模式步局限某个平台
model + View + Controller(模型+ 试图 +控制器)
模型: 主要负责存储和操做的数据,理论上是和View没有联系的
视图:负责展现数据和处理用户之间的交互
控制器:主要前二者联系起来;
达到模型和视图分离的效果,低偶和,单独修改或添加没有影响,复用很是方便,利于扩展和后期的维护,提升软件的开发效率,节约了开发成本。
三、内存管理
arc 和 mrc, xcode5.0后都是自动的
arc原理和自动释放池原理,retain,copy,assgin,一个完整操做都会有一个自动释放池
weak不能修饰基本数据类型,只能修饰对象(assgin 和 weak 相似,但上面有两个不一样,weak修饰的对象销毁后,会自动置空 ,因此更安全)
-fno-objc-arc / fobjc-arc
问题:arc 中批量建立对象,没法作到及时对象(for循环)
细节:xib 中的控件是weak修饰的,由于它们是添加到view上,防止强强引用
内存查的工具,真机的状况下, instruments (专门的例子)
四、试图控制器的生面周期(view 的生命周期)(内存优化的意识)
内存告急的处理(手动释放不可见视图的内存和成员变量),将没有释放的,手动去释放
这样以后会从新调用loadView viewDidLoad
五、cell的重用机制,重用的对象
(iOS6 以后的重用机制,能够提早注册cell)
六、多线程的东西
异步加载数据,至关于与应用多线程,UI主线程(分配的资源是最多的),分开了一段
什么场景的时候应用 多线程------耗时操做(数据库中的读取,图片的处理(滤镜))
七、图片操做;imageNamed: 加载小图片,缓存文件会自动清空,不占用程序的活跃内存。imageNamed的优势是当加载时会缓存图片。因此当图片会频繁的使用时,那么用imageNamed的方法会比较好
iamgeWithContentsFile:大图片。每次调用,会占缓存
imageWithContentsOfFile:仅加载图片,图像数据不会缓存。所以对于较大的图片以及使用状况较少时,那就能够用该方法,下降内存消耗。
八、kvc kvo (点语法是kvc的一种,一种特殊的kvc)
kvc : 内部批量调用 数组的名称 setValueForUnder
kvo : 对符合kvc进行键值观察
九、多线程 NSThread(系统的基本类) NSOperation、 GCD(结合着block 去应用)
AFNetworking code 2.0
效率: block delegate 通知中心
block 是一个匿名函数,
十、为了防止多个线程同时来使用 ,线程锁、syscn...
十一、FMDB 有一个线程安全,作了线程安全(FMDBQ)
sqlite3 事物:try-catch,能提升效率,增长能够看一下啊
若是咱们的app须要多线程操做数据库,那么就须要使用FMDatabaseQueue来保证线程安全了。切记不能在多个线程中共同一个FMDatabase对象而且在多个线程中同时使用,这个类自己不是线程安全的,这样使用会形成数据混乱等问题。
使用FMDatabaseQueue很简单,首先用一个数据库文件地址来初使化FMDatabaseQueue,而后就能够将一个闭包(block)传入inDatabase方法中。在闭包中操做数据库,而不直接参与FMDatabase的管理。
十二、HTTP 协议,TCP,UDP
http: 请求头、相应头、请求体、相应体
1三、oauth2.0
14 IOS6,IOS7,iOS8 增长了三个库(智能家居的,手表的)
iOS6 和 iOS7 一、 拟物化风格(现实生活) 和 扁平化风格(一切事物都变成线条的)二、原点的位置的不一样, 三、 某些方法是不一样的
sprite kit (游戏引擎) / NSURLSeeion(可能代替 NSOperation)