MENU

iOS面试题练习(一)

February 25, 2017 • Read: 428 • iOS

前言

大三下半学期了,准备开始找实习.最近很多公司都已经开始招暑假实习生.在开始看面试题,觉得自己有很多很多知识不知道,即使知道的也不够扎实,这里写出来作为复习资料也给大家一个参考.下面直接开始.

面试问题

什么是ARC?

  • ARC就是自动引用计数,是为了减少开发程序的工作量、降低程序崩溃、内存泄露的风险。与自动引用计数相对的是手动引用计数(MRC)。在MRC中,程序员需要知道什么时候该使用retain/release/dealloc来避免内存泄露等风险。在ARC中编译器则帮我们做了这些事,它会在合适的地方帮我们插入内存管理语句。
  • 而引用计数,则是内存管理机制。当一个对象被创建出来它的引用计数就为一,如果有其他变量指向它(使用它)它的引用计数就会加一。当外部一个引用断开时,该对象的引用计数值就会减一,如果最后一个引用断开的时候,那么对象的引用计数值就会减为0,此时外部再没有使用该对象的变量,所以对象被销毁。
  • 在MRC中,我们可以使用[obj retainCount]来获取对象的引用计数值,但是不推荐这么做,因为这样获得的值不准确。在对象的引用计数为1的时候,外界的最后一个引用断开,按道理此时对象的引用计数值应该为0,然后被销毁。但是,因为对象已经没有作用,编译器就会标记这个对象,在合适的时间销毁它,既然在未来不确定的某个时间点,对象肯定会被销毁,就没有必要浪费资源增加一个引用计数值减一的操作了。
  • ARC也不是万能的,它同样会造成内存泄露:循环引用和野指针。这些都需要程序员注意。

请解释以下keywords的区别: assign vs weak,__block vs __weak

  • 在arc中,可能会出现循环引用的问题,而weak则可以解决此问题,weak是对象的一种弱引用,但原本的对象销毁了之后,weak属性会自动赋值为nil。当在Block中调用了self,此时self持有Block,Block也持有self,此时会造成循环引用,而将self声明为weakSelf,即Block持有Self的弱引用,一方是强引用,一方是弱引用,当强引用断开,那么弱引用也随之断开,就不会造成循环引用了。在设置weak属性的时候,既不保留新值,也不释放旧值。
  • assign主要用于基础数据类型NSInteger等和C数据类型 int,float,char,double等,还有id 类型。assign也可以修饰对象,但是assign属性所指向的对象在销毁后,指针并不会赋值为nil,会造成野指针。而基础数据类型和C数据类型分配在栈控件上,由系统管理,所以不会造成野指针。

__block在ARC和非ARC下含义一样吗?

  • 不一样。在ARC下,__block修饰的属性会retain+1,而非ARC则不会。例如在非ARC中可以直接使用__block typeof(self) weakSelf = self ,然后在Block中使用weakSelf来对self进行操作,而在ARC中,因为__block会对属性引用计数加一,所以需要使用__weak。

+(void)load;+(void)initialize;有什么好处?

  • 在Objective-C中,runtime会自动调用每个类的两个方法。+load会在类初始加载时调用,+initialize会在一次调用类的类方法或实例方法之前被调用。这两个方法是可选的,且只有在实现了它们时才会被调用.因为两个方法是在程序运行一开始就被调用的方法,我们可以做一些预处理工作.

为什么其他语言里叫函数调用,Objective-C里则是给对象发消息(或者谈下对runtime的理解)

  • OC利用[obj message]的方式给对象发送消息,其实会被编译器转换为objc_msgSend(obj, message,arg1,arg2...)。利用这个函数将消息传递给对象,如果对象有这个方法,那么就执行下去。但是如果没有,要么执行消息转发,要么临时向对象动态添加这个massage,最后就是崩溃。
  • 在编译阶段,只是确定了要向接收者发送消息,但什么时候响应,就需要看运行时发生的情况来决定了。
  • 消息转发有3层,第一层是+ (BOOL)resolveInstanceMethod:(SEL)sel方法或者是+ (BOOL)resolveClassMethod:(SEL)sel这就看是类方法还是对象方法了。当这里没有找到的时候,就转发到- (id)forwardingTargetForSelector:(SEL)aSelector方法,当这里还没找到的时候,就会最后一次尝试去找- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector- (void)forwardInvocation:(NSInvocation *)anInvocation,前者为方法生成方法签名,如果没有生成方法签名,则没有这个方法,会返回一个空的签名给后者,然后导致程序崩溃。如果在前者中执行处理,生成了签名,则转发成功。程序继续。

什么是method swizzling?

  • 就是OC中的黑魔法。OC中调用方法是向对象发送一个消息,而我们因为OC动态特性,可以偷梁换柱,替换消息对应的方法实现。
  • 每一个类都有一个方法列表,存放着消息名字和方法实现的映射关系。修改消息名字和方法实现的映射关系,就改变了消息对应的方法实现。我们可以利用method_exchangeImplementations来交换消息中的方法实现;利用class_replaceMethod来修改类,利用method_setImplementation设置方法。

UIView和CALayer是什么关系?

  • UIView是所有iOS中界面元素的基础,所有的界面元素都继承自它。他本身完全是由Core Animation来实现的。但是它仅仅负责界面的显示,而真正绘图的部分就是CALayer来管理。
  • UIView继承自UIResponder,而CALayer继承自NSObject,所以UIView可以响应用户事件,而CALayer则不行。
  • 在UIView类中有个layer属性,UIView更像是CALayer的管理者,CALayer绘制出的图形由UIView来展示,并且实现一些用户事件。

如何高性能的给UIImageView加个圆角

  • 可以利用layer.cornerRadius,但是用这个方法可能会造成离屏渲染,而离屏渲染会消耗大量资源,如果大量使用这个方法会造成内存大量消耗。
  • 可以使用贝塞尔曲线来绘制,使用Core Graphics框架来进行CPU渲染而不是GPU离屏渲染。

使用DrawRect有什么影响?

  • 使用drawRect的话,当在处理touch事件的时候,会进行重绘。如果有很多这样的按钮,就会影响效率。

ASIHttpRequest或者SDWebImage给UIImageView加载图片的逻辑是什么样子的?

  1. 设置一个展位图(可选择);
  2. 根据URL去内存中找,找到返回图片
  3. 内存找不到,硬盘找,找到返回图片,内存做备份
  4. 硬盘还找不到,去下载,返回图片,并进行存储(硬盘,内存)。

参考

iOS中级面试题
知乎上的一个怎么面试iOS工程师的问题

Archives QR Code
QR Code for this page
Tipping QR Code
Leave a Comment

已有 1 条评论
  1. 吴先生 吴先生

    hi