这段时间一直忙着面试找工作,面试的过程中暴露出自己一些问题,还是基础不够扎实,虽然做了三年IOS开发了,但是仅仅是编码上和架构上还可以,基础的东西好多都不知道,太不应该了,所以决心好好把IOS基础的东西都补一补,下面把面试问的问题罗列一下(共参考)。
1. 为什么用weak和assgin去修饰delegate? 用strong或者retain 为什么会引起循环引用?
(1)assgin一般用在非Arc中去修饰delegate,weak是用在Arc中。
(2)weak会在delegate不使用释放的时候自动设置为nil,防止悬垂指针。
(3)如果用strong 或者retain 去修饰delegate 会引起循环引用,原因就是Controller A 中创建的 Controller B 的delegate=A,如果用retain或者strong去修饰的话,A要 释放的时候,因为B对A有引用,所以A不会被释放,同理B也不会被释放,这样就引起循环引用了。
2. Core Foundation 对象 与 Object- C 对象如何转化?(用CFStringRef 与NSString来说明)
(1) 在非ARC情况下,两者只要强制转化即可,如: CFStringRef str1 = (CFStringRef)str2; (str2为NSString对象)
NSString *str3 = (NSString *)str4; (str4为CFStringRef)
(2) 在ARC情况下,就需要用到__bridge 转化了,具体为CFStringRef str1 = (__bridgeCFStringRef)str2 (str2为NSString对象), NSString *str3 = (__bridgeNSString*)str4; (str4为CFStringRef),但是__bridge修饰会引起很大的安全性,不能解决管理赋值对象的所有权问题,会引起悬垂指针。
(3)一般用__bridge_retained 和 __bridge_transfer来进行转化,如:NSString *str2 = (__bridge_transferNSString *)str3; (str3为CFStringRef对象) ; CFStringRef str4 = (__bridge_retainedCFStringRef)str1;(str1为NSString对象),__bridge_transfer被转化的变量所持有的对象在该变量被赋值给转化目标变量后随之释放了。
(4)__bridge_retained和__bridge_transfer分别可以用CFBridgingRetain和CFBridgingRelease来替代
3. 当遇到内存警告的时候会如何处理?
(1)首先分析引起内存警告的原因,不外乎有两种:一种就是存在内存泄露引起的,一种就是加载的资源过多。
(2)针对第一种情况就需要用工具去分析内存泄露的原因。
(3)针对第一种情况,系统会调用UIApplication::didReceiveMemoryWarning-> UIApplicationDelegate::applicationDidReceiveMemoryWarning,然后调用当前所有的viewController进行处理,以便释放掉一些资源。
(4)IOS6以前的处理:didReceiveMemoryWarning->viewDidUnload ,在viewDidUnload中释放资源。
(5)IOS6以后的处理:IOS 6废弃了viewDidUnload方法,这就意味着一切需要我们自己在didReceiveMemoryWarning中操作。清理一些缓存数据 和释放相应的子View,需要判断一下view是否是window的一部分,用if(self.isViewLoaded && !self.view.window){self.view = nil};
4. nil, Nil, NSNull 和 NULL分别代表什么?在什么情况下使用
nil:指向一个对象的空指针
Nil:指向一个类的空指针
NULL:指向其他类型(如:基本类型、C类型)的空指针
NSNull:通常表示集合中的空值
5. AutoRelease 修饰的对象,在什么时候会被释放?
(1)每个应用程序会创建一个根自动释放池。
(2)创建的Autorelease对象不再使用的时候,会被最近的释放池释放掉,一般在NSRunLoop结束的时候,会释放自动释放池中的东西。(对于每一个Runloop, 系统会隐式创建一个Autorelease pool(自然会有多个Autorelease pool),这样所有的release pool会构成一个象CallStack一样的一个栈式结构,在每一个Runloop结束时,当前栈顶的Autorelease pool会被销毁,这样这个pool里的每个Object会被release。)
6. autoreleasepool 调用release和drain有什么不同?
在一个garbage collected环境里,release不做任何操作。 NSAutoreleasePool因此提供了一个 drain 方法,它在reference-counted环境中的行为和调用release一样, 但是在一个garbage collected环境中则触发garbage collection动作.
7. 实现一个NSString 类?
+ (id) stringWithCString: (const char*)nullTerminatedCString encoding: (NSStringEncoding)encoding { NSString *obj; obj = [self allocWithZone: NSDefaultMallocZone()]; obj = [obj initWithCString: nullTerminatedCString encoding: encoding]; return AUTORELEASE(obj); }
8. int 和 NSInteger 有什么不同?
NSInteger不用考虑设备是32位的还是64位的,在32位系统中是int,在64位系统中是long。
9. 如何适配x64位系统,从32位上开发的程序如何升级到64位?
需要注意的问题:
(1). 更新第三方库,用于支持x64位系统。
(2). 增加arm64的architecture
(3)包含汇编代码,因为32位架构和64位架构有及其巨大的区别,根本不可能混用代码,具体情况具体分析
(4)sizeof
(5)指针和整数的互换
(6)int和NSInteger区分,unsigned int和NSUInteger区别,一定用使用NSInteger和NSUInteger
10. 列举三种延时操作的方法。
NSTimer, performSelector, dispatch_after