1、基础问答汇总:参考、参考2、参考3、参考4、参考5、参考6
- copy返回的都是不可变对象,所以如果对copy返回值去调用可变对象的接口就会crash. (好像解答了上述问题)
- mutableCopy 返回的都是可变对象
2、https加密过程:
3、如何优化iOS程序性能:参考1、参考2、Instruments-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、事件传递响应链:参考
13、swift教程:参考
14、iPhoneX适配:参考
框架.png
- CoreGraphics是这是一个C语言写就的库,系统绘制界面、文字、图像等UI的基础。
- 这是一个基于CoreGraphics API的绘图框架,系统中并没有Quartz2D.framework这么一个库,他只是包含了CoreGraphics中的部分API,是一个抽象的引擎,并不是一个实体。
16、字典转模型:参考
19、UIViewController的生命周期:参考
网友评论