copy面试合集(二)
1.UITableview的优化方法(缓存高度,异步绘制,减少层级,hide,避免离屏渲染)
缓存高度:当我们创建frame模型的时候,计算出来cell的高度的时候,我们可以将cell的高度缓存到字典里面,以cell的indexpath
和Identifier
作为为key。
**1. NSString *key = [[HeightCache shareHeightCache] makeKeyWithIdentifier:@"YwywProductGradeCell" indexPath:indexPath];
- if ([[HeightCache shareHeightCache] existInCacheByKey:key]) {
- return [[HeightCache shareHeightCache] heightFromCacheWithKey:key];
- }else{
- YwywProductGradeModelFrame *modelFrame = self.gradeArray[indexPath.row];
- [[HeightCache shareHeightCache] cacheHieght:modelFrame.cellHight key:key];
- return modelFrame.cellHight;
- }
**
异步绘制、减少层级:目前还不是很清楚
hide:个人理解应该是hidden
吧,把可能会用到的控件都创建出来,根据不同的情况去隐藏或者显示出来。
避免离屏渲染:只要不是同时使用边框/边框颜色以及圆角的时候
,都可以使用layer直接设置。不会造成离屏渲染。
.AFN为什么添加一条常驻线程?
AFN 目的:就是开辟线程请求网络数据。如果没有常住线程的话,就会每次请求网络就去开辟线程,完成之后销毁开辟线程,这样就造成资源的浪费,开辟一条常住线程,就可以避免这种浪费,我们可以在每次的网络请求都添加到这条线程。
.KVO的使用?实现原理?(为什么要创建子类来实现)
kvo:键值观察,根据键对应的值的变化,来调用方法。 注册观察者:addObserver:forKeyPath:options:context: 实现观察者:observeValueForKeyPath:ofObject:change:context: 移除观察者:removeObserver:forKeyPath:(对象销毁,必须移除观察者) 注意 使用kvo监听A对象的时候,监听的本质不是这个A对象,而是系统创建的一个中间对象
NSKVONotifying_A
并继承A对象,并且A对象的isa指针指向的也不是A的类,而是这个NSKVONotifying_A
对象\
Objective-C Runtime 是什么?
Objective-C 的 Runtime 是一个运行时库(Runtime Library),它是一种主要使用 C 和汇编写的库,为 C 添加了面相对象的能力并创造了 Objective-C。这就是说它在类信息(Class information) 中被加载,完成所有的方法分发,方法转发,等等。Objective-C runtime 创建了所有需要的结构体,让 Objective-C 的面相对象编程变为可能。
GCD的实现 队列组式
- (void) methodone{ dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ NSLog(@"%d",1); });
dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ NSLog(@"%d",2); });
dispatch_group_notify(group, dispatch_get_main_queue(), ^{ NSLog(@"3");
dispatch_group_t group1 = dispatch_group_create();
dispatch_group_async(group1, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"%d",4);
});
dispatch_group_async(group1, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"%d",5);
});
});
}
主队列是GCD自带的串行队列,会在主线程中执行。异步全局并发队列 开启新线程,并发执行。
并行队列里开启同步任务是有执行顺序的,只有异步才没有顺序。
串行队列开启异步任务,是有顺序的。
串行队列开启异步任务后嵌套同步任务造成死锁。
、static作用?
(1)函数体内 static 变量的作用范围为该函数体,不同于 auto 变量,该变量的内存只被分配一次,因此其值在下次调用时仍维持上次的值;
(2)在模块内的 static 全局变量可以被模块内所用函数访问,但不能被模块外其它函数访问;
(3)在模块内的 static 函数只可被这一模块内的其它函数调用,这个函数的使用范围被限制在声明
它的模块内;
(4)在类中的 static 成员变量属于整个类所拥有,对类的所有对象只有一份拷贝;
(5)在类中的 static 成员函数属于整个类所拥有,这个函数不接收 this 指针,因而只能访问类的static 成员变量。 ————————————————
网络模块:
1、http 的发展历史 以及https的相对于http的加密过程
2、分别说一下tcp 和 udp 以及他们的区别和联系;
3、http的超时默认从什么位置开始计算
4、http使用udp还是tcp链接以及每次发送一个http请求 就一定建立tcp链接吗 为什么
5、tcp三次握手链接 四次断开链接 问:tcp存在四次握手链接吗 以及tcp存在三次握手断开链接吗?
6、为啥是出现四次握手?
7、tcp建立了几个通道 ,分别是什么 ,发送端和接收端是同一个通道吗? ————————————————
.RunLoop的运行模式
RunLoop的运行模式共有5种,RunLoop只会运行在一个模式下,要切换模式,就要暂停当前模式,重写启动一个运行模式
1 kCFRunLoopDefaultMode, App的默认运行模式,通常主线程是在这个运行模式下运行
2 UITrackingRunLoopMode, 跟踪用户交互事件(用于 ScrollView 追踪触摸滑动,保证界面滑动时不受其他Mode影响)
3 kCFRunLoopCommonModes, 伪模式,不是一种真正的运行模式
4 UIInitializationRunLoopMode:在刚启动App时第进入的第一个Mode,
5 GSEventReceiveRunLoopMode:接受系统内部事件,通常用不到
.runloop内部逻辑?
-
实际上 RunLoop 就是这样一个函数,其内部是一个 do-while 循环。当你调用 CFRunLoopRun() 时,线程就会一直停留在这个循环里;直到超时或被手动停止,该函数才会返回。
\
.runloop内部逻辑?
-
实际上 RunLoop 就是这样一个函数,其内部是一个 do-while 循环。当你调用 CFRunLoopRun() 时,线程就会一直停留在这个循环里;直到超时或被手动停止,该函数才会返回。
\
.runloop内部逻辑?
-
实际上 RunLoop 就是这样一个函数,其内部是一个 do-while 循环。当你调用 CFRunLoopRun() 时,线程就会一直停留在这个循环里;直到超时或被手动停止,该函数才会返回。
\
.runloop内部逻辑?
-
实际上 RunLoop 就是这样一个函数,其内部是一个 do-while 循环。当你调用 CFRunLoopRun() 时,线程就会一直停留在这个循环里;直到超时或被手动停止,该函数才会返回。
\
AFNetworking 中如何运用 Runloop? AFURLConnectionOperation 这个类是基于 NSURLConnection 构建的,其希望能在后台线程接收 Delegate 回调。为此 AFNetworking 单独创建了一个线程,并在这个线程中启动了一个 RunLoop:
-
(void)networkRequestThreadEntryPoint:(id)__unused object { @autoreleasepool { [[NSThread currentThread] setName:@"AFNetworking"]; NSRunLoop *runLoop = [NSRunLoop currentRunLoop]; [runLoop addPort:[NSMachPort port] forMode:NSDefaultRunLoopMode]; [runLoop run]; } }
-
(NSThread *)networkRequestThread { static NSThread *_networkRequestThread = nil; static dispatch_once_t oncePredicate; dispatch_once(&oncePredicate, ^{ _networkRequestThread = [[NSThread alloc] initWithTarget:self selector:@selector(networkRequestThreadEntryPoint:) object:nil]; [_networkRequestThread start]; }); return _networkRequestThread; }
今天先到这里哈,挺久没更了。请多多关注哈
【腾讯文档】更多资料分享 docs.qq.com/doc/DZXpKSU…
转载自:https://juejin.cn/post/6988031792699670536