iOS知识汇总(面试宝典)

1、基础问答汇总:参考参考2参考3参考4参考5参考6

  • copy返回的都是不可变对象,所以如果对copy返回值去调用可变对象的接口就会crash. (好像解答了上述问题)
  • mutableCopy 返回的都是可变对象

2、https加密过程:

https

3、如何优化iOS程序性能:参考1参考2Instruments-Core Animation设置圆角&避免离屏渲染的几种方法Instruments-time profile

Instruments-time profile Tips

  • alt + 鼠标滚轮 -> 缩放时间轴
  • shift + 鼠标滚轮 -> 移动时间轴
  • 按住鼠标框选 -> 选择和定位时间轴

4、runtime相关知识:参考

5、runloop相关知识:参考

例题1:看下面一段代码
写下Log的输出,并解释为什么。

- (void)viewDidLoad {
    [super viewDidLoad];
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        NSLog(@"before perform");
        [self performSelector:@selector(printLog) withObject:nil afterDelay:0];
        NSLog(@"after perform");
    });
}
- (void)printLog {
    NSLog(@"printLog");
}

解答:
考察点:GCD并发队列实现机制,以及performSelector的实现原理以及runloop了解。
上面这段代码,只会打印before perform和after perform,不会打印printLog。
原因:

  • GCD默认的全局并发队列,在并发执行任务的时候,会从线程池获取可执行任务的线程(如果没有就阻塞)。
  • performSelector的原理是设置一个timer到当前线程Runloop,并且是NSDefaultRunLoopMode;
  • 非主线程的runloop默认是不启用;

例题2:NStimer准吗?谈谈你的看法?如果不准该怎样实现一个精确的NSTimer?

1.不准

2.不准的原因如下:

1、NSTimer加在main runloop中,模式是NSDefaultRunLoopMode,main负责所有主线程事件,例如UI界面的操作,复杂的运算,这样在同一个runloop中timer就会产生阻塞。

2、模式的改变。主线程的 RunLoop 里有两个预置的 Mode:kCFRunLoopDefaultMode 和 UITrackingRunLoopMode。

当你创建一个 Timer 并加到 DefaultMode 时,Timer 会得到重复回调,但此时滑动一个ScrollView时,RunLoop 会将 mode 切换为 TrackingRunLoopMode,这时 Timer 就不会被回调,并且也不会影响到滑动操作。所以就会影响到NSTimer不准的情况。

PS:DefaultMode 是 App 平时所处的状态,rackingRunLoopMode 是追踪 ScrollView 滑动时的状态。

方法一:

1、在主线程中进行NSTimer操作,但是将NSTimer实例加到main runloop的特定mode(模式)中。避免被复杂运算操作或者UI界面刷新所干扰。

self.timer = [NSTimer timerWithTimeInterval:1 target:self selector:@selector(showTime) userInfo:nil repeats:YES];

[[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];

2、在子线程中进行NSTimer的操作,再在主线程中修改UI界面显示操作结果;

- (void)timerMethod2 {
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(newThread) object:nil];
[thread start];
}
- (void)newThread
{
@autoreleasepool
{
[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(showTime) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] run];
}
}

总结:

一开始的时候系统就为我们将主线程的main runloop隐式的启动了。

在创建线程的时候,可以主动获取当前线程的runloop。每个子线程对应一个runloop

方法二:
直接使用GCD替代!

6、NSURLSession与NSURLConnection区别 :参考

7、iOS消息传递:参考

8、iOS 系统架构及常用框架:参考

  • Cocoa Touch:UIKit、MapKit…
  • Media Layer:AVFoundation、CoreGraphics、QuartzCore
  • Core Services:WebKit、CFNetwork、Foundation
  • Core OS

9、UIView和CALayer之间的关系:

  • UIView处于UIKit框架中,CALayer处于QuartzCore框架中
  • UIView处于Cocoa Touch层,QuartzCore处于Media Layer层
  • UIView作为CALayer的代理对象
  • UIView主要关心事件处理,CALayer关心页面绘制
  • UIView只是返回了CALayer的属性

10、面向对象和面向过程的区别:

  • 面向过程
    分析出解决问题所需要的步骤,然后使用函数把这些步骤一步一步实现(函数可以封装一系列动作为了做一件事情,也就是面向过程也存在封装的思想)
  • 面向对象
    把构成问题的事务分解为不同的对象,建立对象的不是为了完成一个步骤,而是为了描述某个事务在解决整个问题中的行为

11、事件传递响应链:参考

12、移动端web优化:参考参考2参考3参考4

13、swift教程:参考

14、iPhoneX适配:参考

15、iOS动画:参考参考2

框架.png
  • CoreGraphics是这是一个C语言写就的库,系统绘制界面、文字、图像等UI的基础。
  • 这是一个基于CoreGraphics API的绘图框架,系统中并没有Quartz2D.framework这么一个库,他只是包含了CoreGraphics中的部分API,是一个抽象的引擎,并不是一个实体。

16、字典转模型:参考

17、ARC相关:参考参考2参考3

18、多线程:参考参考2参考3

19、UIViewController的生命周期:参考

20、数据库FMDB:参考1参考2参考3

发表评论

电子邮件地址不会被公开。 必填项已用*标注