116道iOS⾯试题+答案,希望对你的⾯试有帮助
之前看了很多⾯试题,感觉要不是不够就是过于冗余,于是我将⽹上的⼀些⾯试题进⾏了删减和重排,现在分享给⼤家。(题⽬来源于⽹络,侵删)
1. Object-c的类可以多重继承么?可以实现多个接⼝么?Category是什么?重写⼀个类的⽅式⽤继承好还是分类好?为什么?
答: Object-c的类不可以多重继承;可以实现多个接⼝,通过实现多个接⼝可以完成C++的多重继承;Category是类别,⼀般情况⽤分类好,⽤Category去重写类的⽅法,仅对本Category有效,不会影响到其他类与原有类的关系。
2. #import 跟#include ⼜什么区别,@class呢, #import<> 跟 #import””⼜什么区别?
作为⼀个开发者,有⼀个学习的氛围跟⼀个交流圈⼦特别重要,这是⼀个我的iOS交流:638302184,不管你是⼩⽩还是⼤⽜欢迎⼊驻 ,分享BAT,阿⾥⾯试题、⾯试经验,讨论技术, ⼤家⼀起交流学习成长!
3. 属性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
**4.写⼀个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;
}
|
5.对于语句NSString*obj = [[NSData alloc] init]; obj在编译时和运⾏时分别时什么类型的对象?
答: 编译时是NSString的类型;运⾏时是NSData类型的对象
6.常见的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。
7.id 声明的对象有什么特性?
答:Id 声明的对象具有运⾏时的特性,即可以指向任意类型的objcetive-c的对象;
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对象加⼊到最内层的系统内存池, 当我们释放这个内存池时, 其中的对象都会被释放.
9. 原⼦(atomic)跟⾮原⼦(non-atomic)属性有什么区别?
答:
1). atomic提供多线程安全。是防⽌在写未完成的时候被另外⼀个线程读取,造成数据错误
2). non-atomic:在⾃⼰管理内存的环境中,解析的访问器保留并⾃动释放返回的值,如果指定了 nonatomic ,那么访问器只是简单地返回这个值。
10. 看下⾯的程序,第⼀个NSLog会输出什么?这时str的retainCount是多少?第⼆个和第三个呢? 为什么?
NSMutableArray* ary = [[NSMutableArray array] retain];
NSString *str = [NSString stringWithFormat:@``"test"``];
mutable是什么意思[str retain];
[aryaddObject:str];
NSLog(@”%@%d”,str,[str retainCount]);
[str retain];
[str release];
[str release];
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
11. 内存管理的⼏条原则时什么?按照默认法则.那些关键字⽣成的对象需要⼿动释放?在和property结合的时候怎样有效的避免内存泄露?
答:谁申请,谁释放
遵循Cocoa Touch的使⽤原则;
内存管理主要要避免“过早释放”和“内存泄漏”,对于“过早释放”需要注意@property设置特性时,⼀定要⽤对特性关键字,对于“内存泄漏”,⼀定要申请了要负责释放,要细⼼。
关键字alloc 或new ⽣成的对象需要⼿动释放;
设置正确的property属性,对于retain需要在合适的地⽅释放,
12.如何对iOS设备进⾏性能测试?
答: Profile-> Instruments ->Time Profiler
13. Object C中创建线程的⽅法是什么?如果在主线程中执⾏代码,⽅法是什么?如果想延时执⾏代码、⽅法⼜是什么?
答:线程创建有三种⽅法:使⽤NSThread创建、使⽤GCD的dispatch、使⽤⼦类化的NSOperation,然后将其加⼊NSOperationQueue;在主线程执⾏代码,⽅法是performSelectorOnMainThread,如果想延时执⾏代码可以⽤
performSelector:onThread:withObject:waitUntilDone:
14. MVC设计模式是什么? 你还熟悉什么设计模式?
答:
设计模式:并不是⼀种新技术,⽽是⼀种编码经验,使⽤⽐如java中的接⼝,iphone中的协议,继承关系等基本⼿段,⽤⽐较成熟的逻辑去处理某⼀种类型的事情,总结为所谓设计模式。⾯向对象中,java已经归纳了23种设计模式。
m设计模式 :模型,视图,控制器,可以将整个应⽤程序在思想上分成三⼤块,对应是的数据的存储或处理,前台的显⽰,业务逻辑的控制。 Iphone本⾝的设计思想就是遵循mvc设计模式。其不属于23种设计模式范畴。
代理模式:代理模式给某⼀个对象提供⼀个代理对象,并由代理对象控制对源对象的引⽤.⽐如⼀个⼯⼚⽣产了产品,并不想直接卖给⽤户,⽽是搞了很多代理商,⽤户可以直接代理商买东西,代理商从⼯⼚进货.常见的如QQ的⾃动回复就属于代理拦截,代理模式在iphone中得到⼴泛应⽤.
单例模式:说⽩了就是⼀个类不通过alloc⽅式创建对象,⽽是⽤⼀个静态⽅法返回这个类的对象。系统只需要拥有⼀个的全局对象,这样有利于我们协调系统整体的⾏为,⽐如想获得[UIApplication sharedApplication];任何地⽅调⽤都可以得到 UIApplication的对象,这个对象是全局唯⼀的。
观察者模式: 当⼀个物体发⽣变化时,会通知所有观察这个物体的观察者让其做出反应。实现起来⽆
⾮就是把所有观察者的对象给这个物体,当这个物体的发⽣改变,就会调⽤遍历所有观察者的对象调⽤观察者的⽅法从⽽达到通知观察者的⽬的。
⼯⼚模式:
public class Factory{
public static Sample creator(``int which){
if(which==``1``)
return new SampleA();
else if(which==``2``)
return new SampleB();
}
}
|
15 浅复制和深复制的区别?
答:浅层复制:只复制指向对象的指针,⽽不复制引⽤对象本⾝。
深层复制:复制引⽤对象本⾝。
意思就是说我有个A对象,复制⼀份后得到A_copy对象后,对于浅复制来说,A和A_copy指向的是同⼀个内存资源,复制的只不过是是⼀个指针,对象本⾝资源
还是只有⼀份,那如果我们对A_copy执⾏了修改操作,那么发现A引⽤的对象同样被修改,这其实违背了我们复制拷贝的⼀个思想。深复制就好理解了,内存中存在了
两份独⽴对象本⾝。
⽤⽹上⼀哥们通俗的话将就是:
浅复制好⽐你和你的影⼦,你完蛋,你的影⼦也完蛋
深复制好⽐你和你的克隆⼈,你完蛋,你的克隆⼈还活着。
16. 类别的作⽤?继承和类别在实现中有何区别?
答:category 可以在不获悉,不改变原来代码的情况下往⾥⾯添加新的⽅法,只能添加,不能删除修改,并且如果类别和原来类中的⽅法产⽣名称冲突,则类别将覆盖原来的⽅法,因为类别具有更⾼的优先级。
类别主要有3个作⽤:
1).将类的实现分散到多个不同⽂件或多个不同框架中。
2).创建对私有⽅法的前向引⽤。
3).向对象添加⾮正式协议。
继承可以增加,修改或者删除⽅法,并且可以增加属性。
17. 类别和类扩展的区别。
答:category和extensions的不同在于 后者可以添加属性。另外后者添加的⽅法是必须要实现的。
extensions可以认为是⼀个私有的Category。
18. oc中的协议和java中的接⼝概念有何不同?
答:OC中的代理有2层含义,官⽅定义为 formal和informal protocol。前者和接⼝⼀样。
informal protocol中的⽅法属于设计模式考虑范畴,不是必须实现的,但是如果有实现,就会改变类的属性。
其实关于正式协议,类别和⾮正式协议我很早前学习的时候⼤致看过,也写在了学习教程⾥
“⾮正式协议概念其实就是类别的另⼀种表达⽅式“这⾥有⼀些你可能希望实现的⽅法,你可以使⽤他们更好的完成⼯作”。
这个意思是,这些是可选的。⽐如我门要⼀个更好的⽅法,我们就会申明⼀个这样的类别去实现。然后你在后期可以直接使⽤这些更好的⽅法。
这么看,总觉得类别这玩意⼉有点像协议的可选协议。”
现在来看,其实protocal已经开始对两者都统⼀和规范起来操作,因为资料中说“⾮正式协议使⽤interface修饰“,
现在我们看到协议中两个修饰词:“必须实现(@requied)”和“可选实现(@optional)”。
19. 什么是KVO和KVC?
答:KVC:键 – 值编码是⼀种间接访问对象的属性使⽤字符串来标识属性,⽽不是通过调⽤存取⽅法,直接或通过实例变量访问的机制。
很多情况下可以简化程序代码。apple⽂档其实给了⼀个很好的例⼦。
KVO:键值观察机制,他提供了观察某⼀属性变化的⽅法,极⼤的简化了代码。
具体⽤看到嗯哼⽤到过的⼀个地⽅是对于按钮点击变化状态的的监控。
⽐如我⾃定义的⼀个button
[self addObserver:self forKeyPath:@``"highlighted"options:``0context: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注:Key-Value Coding查⽅法的时候,不仅仅会查someKey这个⽅法,还会查getsomeKey这个⽅法,前⾯加⼀个get,或者_someKey以及_getsomeKey这⼏种形式。同时,查实例变量的时候也会不仅仅查someKey这个变量,也会查
_someKey这个变量是否存在。)
设计valueForUndefinedKey:⽅法的主要⽬的是当你使⽤-(id)valueForKey⽅法从对象中请求值时,对象能够在错误发⽣前,有最后的机会响应这个请求。这样做有很多好处,下⾯的两个例⼦说明了这样做的好处。“
来⾄cocoa,这个说法应该挺有道理。
因为我们知道button却是存在⼀个highlighted实例变量.因此为何上⾯我们只是add⼀个相关的keypath就⾏了,
可以按照kvc查的逻辑理解,就说的过去了。
20. 代理的作⽤?
答:代理的⽬的是改变或传递控制链。允许⼀个类在某些特定时刻通知到其他类,⽽不需要获取到那些类的指针。可以减少框架复杂度。
另外⼀点,代理可以理解为java中的回调监听机制的⼀种类似。
21. oc中可修改和不可以修改类型。
答:可修改不可修改的集合类。这个我个⼈简单理解就是可动态添加修改和不可动态添加修改⼀样。
⽐如NSArray和NSMutableArray。前者在初始化后的内存控件就是固定不可变的,后者可以添加等,可以动态申请新的内存空间。
22. 我们说的oc是动态运⾏时语⾔是什么意思?
答:多态。 主要是将数据类型的确定由编译时,推迟到了运⾏时。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论