1.MVC跟MVP的区别以及使用的优缺点?
MVC:View和控制器耦合性强
MVP:面向协议,View和Model完全解耦,Controller层不显示网络请求数据的过程,只要遵循协议就能拿到数据
MVVM: KVO双向绑定
2.怎么解决iOS打包成功之后,运行在iPhone上会闪退,黑屏的问题
1.证书有错误(发布证书打包AppStore)
2.设备不在开发者设备里面
3.隐私权限字段未添加
如何解决
查看:embedded.mobileprovision, cd 到这个文件的目录下
security cms -D -i embedded.mobileprovision > entitlements_full.plist
3.OC中字典的实现原理
哈希表: 本质就是一个数组
哈希算法
通过哈希函数算出它的位置,直接从数组中取,不用遍历,提高了查找速度(时间复杂度底)。
字母重复时:开放地址法,给个增量
4.SDWebImage是怎么来清理缓存的?
1.找到磁盘缓存目录
2.找到resourceKey
3.创建目录文件的枚举器(NSDirectotyEnumerator)
4.计算过期时间(可以设置最大缓存时间)
5.删除文件
①根据过期时间,7天过期删除
②把之前的没删除的按时间顺序存起来,根据自定义的最大缓存删除一半,直到缓存达到一半为止
5.SDWebImage是怎么来处理接收的内存警告的?
使用clearMemory方法清空内存缓存
继承于NSCache, AutoPurgeCache自动清理缓存
6.计算图片的成本大小
计算图片所占内存大小
SDCacheCostForImage
获取缓存中所有文件大小,通过NSDirctoryEnumerator,遍历磁盘缓存路径
7.SDWebImage中Clear和和Clean有什么区别?
- clean 部分删除,磁盘缓存(1.过期的缓存文件2.缓存超过设定阈值时按时间顺序删除缓存中图片阈值的一半)
- clear全部删除,包括文件夹(1.删除缓存目录2.创建同名的缓存目录)
8.iOS静态库和动态库的区别
静态库:链接时会被完整的复制到可执行文件中,被多次使用就会有多份拷贝
动态库:链接时不复制,程序运行时由系统动态加载到内存,系统只加载一次,节省内存。
将程序编译成可执行文件
clang -ccc-print-phases main.m
静态库和动态库区别就在于linker
9.Block的理解,外部变量的修改
1.block的定义
void (^block)(void) = ^{
NSLog(@"block");
}
block()
2.block的分类
①NSGlobalBlock 全局block(不引入外部变量)
②NSMallocBlock 堆block
(引入外部变量)
③NSStackBlock 栈block
(函数返回后Block将无效)
3.修改外部变量
__block(将观察到的对象由栈区copy到堆区)
10.回到主线程方案
- ①
NSThread
[self performSelectorOnMainThread:@selector(WantToGoBackMianThread:) withObject:@"1" waitUntilDone:YES];
- ②
NSOperationQueue
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
//需要在主线程执行的代码
}];
- ③
GCD
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"更新UI%@",[NSThread currentThread]);
});
面试集锦之开发常见问题
1.OC中处理json解析出NSCFString
//注意:
NSDictionary * homeworkDic;
if ([[dict valueForKeyPath:@"data.homework"] isKindOfClass:[NSDictionary class]]) {
homeworkDic = [dict valueForKeyPath:@"data.homework"];
}else
{
homeworkDic = [self dictionaryWithJsonString:[dict valueForKeyPath:@"data.homework"]];
}
2.根据网络状态加载图片
- 先从磁盘中获得原图 -> 原图已经被下载过->直接显示
- 原图并未下载过-> WiFi直接下载原图
- 原图并未下载过-> 3G\4G网络下时候要下载原图
- 原图并未下载过-> 没有可用网络,此时从磁盘缓存中查找缩略图
- 缩略图已经被下载过-> 直接显示
- 没有下载过任何图片-> 显示占位图(placeholder)
3.ViewWithTag-查找子控件报错
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
// 求出标题按钮的索引
NSUInteger index = scrollView.contentOffset.x / scrollView.width;
// index == [0, 4]
// 点击对应的标题按钮
HKTitleButton *titleButton = self.titlesView.subviews[index];
//HKTitleButton *titleButton = [self.titlesView viewWithTag:index];
//此代码 索引为0时会报错(viewWithTag 递归查找,包括自己 先查找自己的tag,再查找子视图的tag,父视图默认tag为0,找到的是UIView而不是Button,所以setSelected方法找不到)
[self titleButtonClick:titleButton];
}
4.iOS12下APP进入后台后再返回前台连接断开
1.在工程的AppDelegate文件中
@property (nonatomic, unsafe_unretained) UIBackgroundTaskIdentifier taskId;
2.在AppDelegate中的- (void)applicationDidEnterBackground:(UIApplication *)application 方法中
self.taskId =[application beginBackgroundTaskWithExpirationHandler]
用完的时候调用endTask
3.模拟一个长时间的任务
4.后台任务结束的时候要释放定时器
5.空数组的处理
if (![array isKindOfClass:[NSNull class]] && array.count > 0 && array != nil) {
}
数据源数组中包含空数组,怎么移除?
if ([self.dataArray containsObject:@[]]) {
[self.dataArray removeObject:@[]];
}
6.在同一页面同时展示登录和注册View
在一个UIView设置它的Frame的宽度是屏幕的两倍,然后把登录的View和注册的View同时加载这个View上(注册View.x=这个View宽度的一半),点击切换按钮时改变这个UIView的leadingConstraint(View.x)就可以让这两个View显示。
7.升级Https证书报错
iOS11 HTTP load failed (error code: -999)
// 1.设置非校验证书模式
_sessionManager.securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeNone];
_sessionManager.securityPolicy.allowInvalidCertificates = YES;
[_sessionManager.securityPolicy setValidatesDomainName:NO];
8.某个页面禁止侧滑手势返回
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
// 禁用返回手势
if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
self.navigationController.interactivePopGestureRecognizer.enabled = NO;
}
}
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
// 开启返回手势
if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
self.navigationController.interactivePopGestureRecognizer.enabled = YES;
}
}