iOS 面试题整理

iOS面试技巧(2020年07月)

2020-07-25  本文已影响0人  鹏飞说

问题和答案

什么是ARC?(ARC是为了解决什么问题而诞生的)

ARC为自动内存管理,与之对应的是MRC(手动内存管理),ARC的出现,使得开发者在无需手动引入retain和release机制,不仅降低了程序崩溃和内存泄漏的风险,而且减少了开发者工作的工作量

assign vs weak __block vs __weak

assign 是用来修饰基本属性的一个关键字,引用计数器不加1
weak 用来修饰对象,不改变对象的引用计数器且不还保留对象实例,可以有效防止循环引用

  1. __block 当我们的变量被block捕获的时候,我们想要去再修改变量的时候就会发现无法修改,这个时候__block修饰变量之后就可以修改这个参数,但是在修改之后由于__block 在ARC下会被block retain 就有可能造成循环引用,需要使用弱引用才能解决这个问题。
  2. __block 在ARC和MRC下是不一样的,只有在ARC下才会引起循环引用
使用atomic一定是线程安全的吗

不是,使用的时候加个线程锁,因为在使用的过程中,如果多个线程对其进行操作的时候,虽然他的set,get方法是有一定的操作序列的,但是有可能会出现某个线程操作的过程中,获取到其他线程的数据的问题

-(void)load

当类对象被引用到项目的时候,runtime都会向每个类发送一个load方法,这个优先级最高,而且不会被自动继承,只会被调用一次

runtime的理解

因为OC是一门动态语言,尽可能的将所有的工作都推迟到运行时才会去调用,它就是基于runtime工作,runtime的核心就是消息发送:objc_msgSend
所有的消息都会在运行时才会确定,[objc message] 会被转化为objc_msgSend(id self,SEL cmd,...)来执行,它会在运行时从选择子表中寻找对应的选择子并将选择子与实现进行绑定,如果没有找到对应的实现,就会进入消息转发机制,调用:

+ (BOOL)resolveInstanceMethod:(SEL)aSelector 

我们可以在这个方法中为类动态的生成方法

  1. 为分类动态的添加方法
  2. 使用自定义方法更换原有方法的实现
  3. 统计在某个界面停留的时长

block的应用场景

Method Swizzling

是一中在运行时动态修改原有方法实现的技术,其实就是runtime的特性,其核心方法就是

method_exchangeImplementations(SEL origin, SEL swizzle)

加载在load中,动态的修改一些系统的方法,不在initialize中调用的原因是initialize可能会被子类所继承并重新执行之后导致无线递归,load方法不会被继承

UIView 和CALayer的区别

UIView 继承自UIResponder 处理用户的点击事件
CALayer继承自NSObject 用于图层的渲染

实现上面两个操作的原因:

其实操作的每一个UIVeiw都是操作了CALayer,因为每一个UIView的背后对应一个Core Animation框架中的CAlayer ,每一个UIView都是CALayer的代理
UIView其实是CALayer的轻量封装

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

使用layer 会强制Core Animation提前渲染屏幕的离屏绘制,而离屏绘制会给性能带来负面形象
我们可以使用贝塞尔曲线给图片添加圆角

UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
imageView.center = CGPointMake(200, 300);
UIImage *anotherImage = [UIImage imageNamed:@"image"];
UIGraphicsBeginImageContextWithOptions(imageView.bounds.size, NO, 1.0);
[[UIBezierPath bezierPathWithRoundedRect:imageView.bounds
                           cornerRadius:50] addClip];
[anotherImage drawInRect:imageView.bounds];
imageView.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[self.view addSubview:imageView];

使用贝塞尔曲线相当于我们切割了这个图片,从而生成的圆角

给UIImageView添加图片的逻辑,如果给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, 完成整个图像的异步下载和配置.

参考自

iOS面试解答

上一篇 下一篇

猜你喜欢

热点阅读