1.MVC跟MVP的區(qū)別以及使用的優(yōu)缺點?
MVC:View和控制器耦合性強
MVP:面向協(xié)議,View和Model完全解耦,Controller層不顯示網絡請求數(shù)據(jù)的過程,只要遵循協(xié)議就能拿到數(shù)據(jù)
MVVM: KVO雙向綁定
2.怎么解決iOS打包成功之后,運行在iPhone上會閃退,黑屏的問題
1.證書有錯誤(發(fā)布證書打包AppStore)
2.設備不在開發(fā)者設備里面
3.隱私權限字段未添加
如何解決
查看:embedded.mobileprovision, cd 到這個文件的目錄下
security cms -D -i embedded.mobileprovision > entitlements_full.plist
3.OC中字典的實現(xiàn)原理
哈希表: 本質就是一個數(shù)組
哈希算法
通過哈希函數(shù)算出它的位置,直接從數(shù)組中取,不用遍歷,提高了查找速度(時間復雜度底)。
字母重復時:開放地址法,給個增量
4.SDWebImage是怎么來清理緩存的?
1.找到磁盤緩存目錄
2.找到resourceKey
3.創(chuàng)建目錄文件的枚舉器(NSDirectotyEnumerator)
4.計算過期時間(可以設置最大緩存時間)
5.刪除文件
①根據(jù)過期時間,7天過期刪除
②把之前的沒刪除的按時間順序存起來,根據(jù)自定義的最大緩存刪除一半,直到緩存達到一半為止
5.SDWebImage是怎么來處理接收的內存警告的?
使用clearMemory方法清空內存緩存
繼承于NSCache, AutoPurgeCache自動清理緩存
6.計算圖片的成本大小
計算圖片所占內存大小
SDCacheCostForImage
獲取緩存中所有文件大小,通過NSDirctoryEnumerator,遍歷磁盤緩存路徑
7.SDWebImage中Clear和和Clean有什么區(qū)別?
- clean 部分刪除,磁盤緩存(1.過期的緩存文件2.緩存超過設定閾值時按時間順序刪除緩存中圖片閾值的一半)
- clear全部刪除,包括文件夾(1.刪除緩存目錄2.創(chuàng)建同名的緩存目錄)
8.iOS靜態(tài)庫和動態(tài)庫的區(qū)別
靜態(tài)庫:鏈接時會被完整的復制到可執(zhí)行文件中,被多次使用就會有多份拷貝
動態(tài)庫:鏈接時不復制,程序運行時由系統(tǒng)動態(tài)加載到內存,系統(tǒng)只加載一次,節(jié)省內存。
將程序編譯成可執(zhí)行文件
clang -ccc-print-phases main.m
靜態(tài)庫和動態(tài)庫區(qū)別就在于linker
9.Block的理解,外部變量的修改
1.block的定義
void (^block)(void) = ^{
NSLog(@"block");
}
block()
2.block的分類
①NSGlobalBlock 全局block(不引入外部變量)
②NSMallocBlock 堆block(引入外部變量)
③NSStackBlock 棧block(函數(shù)返回后Block將無效)
3.修改外部變量
__block(將觀察到的對象由棧區(qū)copy到堆區(qū))
10.回到主線程方案
- ①
NSThread
[self performSelectorOnMainThread:@selector(WantToGoBackMianThread:) withObject:@"1" waitUntilDone:YES];
- ②
NSOperationQueue
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
//需要在主線程執(zhí)行的代碼
}];
- ③
GCD
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"更新UI%@",[NSThread currentThread]);
});
面試集錦之開發(fā)常見問題
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.根據(jù)網絡狀態(tài)加載圖片
- 先從磁盤中獲得原圖 -> 原圖已經被下載過->直接顯示
- 原圖并未下載過-> 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.空數(shù)組的處理
if (![array isKindOfClass:[NSNull class]] && array.count > 0 && array != nil) {
}
數(shù)據(jù)源數(shù)組中包含空數(shù)組,怎么移除?
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;
}
}