準(zhǔn)備:
1.iOS的數(shù)據(jù)持久化方案
所有的本地持久化數(shù)據(jù)存儲(chǔ)的本質(zhì)都是寫文件,而且只能存到沙盒中。
沙盒機(jī)制是蘋果的一項(xiàng)安全機(jī)制纹腌,本質(zhì)就是系統(tǒng)給每個(gè)應(yīng)用分配了一個(gè)文件夾來存儲(chǔ)數(shù)據(jù),而且每個(gè)應(yīng)用只能訪問分配給自己的那個(gè)文件夾滞磺,其他應(yīng)用的文件夾是不能訪問的升薯。
數(shù)據(jù)存儲(chǔ)的核心都是寫文件。主要有四種持久化方式:屬性列表击困,對(duì)象序列化涎劈,SQLite 數(shù)據(jù)庫, CoreData
2.常用的SQL語句
insert into values
delete from where
update set where
select from where
3.會(huì)哪些前端框架
Vue element-ui
4.Vue的特性
輕量級(jí)阅茶、雙向數(shù)據(jù)綁定蛛枚、指令、組件化脸哀、客戶端路由蹦浦、狀態(tài)管理
6.iOS系統(tǒng)架構(gòu)
從下到上:Core OS(核心操作系統(tǒng)層)、Core Services(核心服務(wù)層)撞蜂、Media (媒體層)盲镶、Cocoa Touch(界面層)
5.block
block本質(zhì)上是一個(gè)OC對(duì)象侥袜,他內(nèi)部也有一個(gè)isa指針。block是封裝了函數(shù)調(diào)用以及函數(shù)調(diào)用環(huán)境的OC對(duì)象溉贿。
一共有三種block枫吧,分別是全局的、棧上的宇色、堆上的九杂。
6.手寫一個(gè)單例
- (LoginManager *)sharedLoginManager
{
if(!sharedLoginManager){
sharedLoginManager = [[self allocWithZone:Null]init];
}
return sharedLoginManager;
}
今天遇到的面試題:
1.傳值的回調(diào)方式有哪些,區(qū)別是什么代兵?
答:
1.目標(biāo)動(dòng)作對(duì)(Targe-Action):這里接受消息的對(duì)象是目標(biāo)(target)尼酿,消息的選擇器(selector)是動(dòng)作(action),一對(duì)一植影,向一個(gè)對(duì)象發(fā)送一個(gè)回調(diào)裳擎。
2.輔助對(duì)象:包括代理(Delegate)和數(shù)據(jù)源(DataSource),一對(duì)一思币,向一個(gè)對(duì)象發(fā)送多個(gè)回調(diào)鹿响。
3.通知(Notification),一對(duì)多谷饿,在程序中如果需要觸發(fā)多個(gè)(其他對(duì)象中)的回調(diào)對(duì)象時(shí)惶我,可以使用通知的方式來完成。
4.Block:誰要傳值誰就定義含有參數(shù)的Block, 誰要調(diào)用誰就執(zhí)行這個(gè)Block博投,通過Block對(duì)象绸贡,可以將回調(diào)相關(guān)的代碼寫在同一個(gè)代碼段中。
總結(jié):這道題我只答出了后三種毅哗,忘記了第一種目標(biāo)動(dòng)作對(duì)听怕,他們的區(qū)別我只答出了delegate和Notification的區(qū)別是一對(duì)一和一對(duì)多,對(duì)于回調(diào)方式的區(qū)別沒有答出來虑绵。
2.block的屬性修飾用什么關(guān)鍵字尿瞭,delegate的屬性修飾用什么關(guān)鍵字,為什么翅睛?assign和weak的區(qū)別声搁?
答:block的屬性修飾詞是copy,默認(rèn)情況下block是存放在棧中捕发,可能隨時(shí)被回收疏旨,通過copy操作可以使其在堆中保留一份,相當(dāng)于一直強(qiáng)引用著爬骤,因此如果block中用到self時(shí)需要將其進(jìn)行弱化充石,通過__weak或者_(dá)_unsafe_unretained。
delegate的屬性修飾關(guān)鍵詞是weak,是為了防止循環(huán)引用骤铃。
weak和assign的區(qū)別:
weak 只可以修飾對(duì)象拉岁。weak不會(huì)產(chǎn)生野指針的問題,因?yàn)閣eak修飾的對(duì)象被釋放后指針會(huì)自動(dòng)置為nil惰爬,之后再向該對(duì)象發(fā)送消息也不會(huì)崩潰喊暖。weak是安全的。
assign 可修飾對(duì)象撕瞧,和基本數(shù)據(jù)類型陵叽。如果修飾對(duì)象,會(huì)產(chǎn)生野指針問題丛版;如果修飾基本數(shù)據(jù)類型則是安全的巩掺。修飾的對(duì)象釋放后,指針不會(huì)被自動(dòng)置空页畦,此時(shí)向?qū)ο蟀l(fā)送消息會(huì)崩潰胖替。
總結(jié):這道題我只答出來了delegate的屬性修飾詞用weak,為了防止循環(huán)引用豫缨,block的屬性修飾詞答成了weak独令,weak是block中self的修飾詞,不是block的修飾詞好芭。self用weak修飾也是因?yàn)閎lock 用了copy燃箭,為了弱化強(qiáng)引用,我沒有答出來主要是以前沒有深刻理解這一塊的內(nèi)容舍败。還有關(guān)于使用weak不會(huì)產(chǎn)生野指針的問題招狸,前兩天剛看過這個(gè)面試題,面試一問我又忘了邻薯,也是因?yàn)闆]有深刻理解瓢颅,光死記硬背是不行的。
3.Category弛说、擴(kuò)展、繼承的區(qū)別翰意,有哪些應(yīng)用場景木人,往Category里可以添加屬性嗎?重寫一個(gè)類的方法用繼承好還是分類好?為什么?如果Category重寫父類的方法冀偶,執(zhí)行Category的方法后還會(huì)執(zhí)行父類中的方法嗎醒第?項(xiàng)目中哪些地方用到了分類?
分類和擴(kuò)展的區(qū)別:
1.分類原則上只能添加方法(能添加屬性的的原因只是通過runtime解決無setter/getter的問題而已)
2.類擴(kuò)展不僅可以增加方法进鸠,還可以增加實(shí)例變量(或者屬性)
3.類擴(kuò)展中聲明的方法沒被實(shí)現(xiàn)稠曼,編譯器會(huì)報(bào)警告,但是分類中的方法沒被實(shí)現(xiàn)編譯器是不會(huì)有任何警告的客年。這是因?yàn)轭悢U(kuò)展是在編譯階段被添加到類中霞幅,而分類是在運(yùn)行時(shí)添加到類中漠吻。
4.類擴(kuò)展不能像分類那樣擁有獨(dú)立的實(shí)現(xiàn)部分(@implementation部分),也就是說司恳,類擴(kuò)展所聲明的方法必須依托對(duì)應(yīng)類的實(shí)現(xiàn)部分來實(shí)現(xiàn)途乃。
5..m文件里的定義屬性,有時(shí)我們不會(huì)在.h里寫屬性扔傅,因?yàn)槟菢訒?huì)變成public耍共,只要import后,外部都可以訪問猎塞。如果我們只想當(dāng)前類用一下试读,只需要寫在.m里面,這樣的屬性或方法其實(shí)也是擴(kuò)展的一種荠耽。
分類與繼承的區(qū)別:
分類只能添加新的方法钩骇,不能刪除修改。
繼承可以增加骇塘、修改伊履、刪除方法。并且可以增加屬性款违。
繼承可以修改父類的已經(jīng)存在方法唐瀑,比如初始化方法init,重寫它之后你可以得到你想要的初始化對(duì)象插爹,而分類則可以擴(kuò)展原有類的方法哄辣,比如你想讓UIImageView可以從網(wǎng)絡(luò)設(shè)置其image對(duì)象,則可以寫一個(gè)分類赠尾,擴(kuò)展這個(gè)原類中沒有的方法(或者說功能)力穗,因此看你的需求是什么,而不是籠統(tǒng)的說誰好誰壞气嫁。
Category重寫父類中的方法当窗,會(huì)覆蓋父類方法,父類方法不會(huì)執(zhí)行寸宵。
繼承重寫一個(gè)方法崖面,不會(huì)影響到其他地方正常使用這個(gè)方法。
項(xiàng)目中用到分類的地方:修改系統(tǒng)分類的樣式梯影、功能巫员,比如為NSDate新增分類,增加新的計(jì)時(shí)方法甲棍,為UIColor新增分類简识,增加新的顏色顯示方法。
總結(jié):這道題也是前兩天看過的面試題,結(jié)果面試時(shí)又把Category七扰、擴(kuò)展奢赂、繼承三者說混了,后來我發(fā)現(xiàn)我的項(xiàng)目中用的都是Category戳寸,沒有用擴(kuò)展呈驶,因?yàn)橛昧藃untime的方法給Category添加屬性。這也使得我沒有真正理解分類和擴(kuò)展的區(qū)別∫呷担現(xiàn)在記住了他們的區(qū)別以后可以嘗試在項(xiàng)目中多用一些擴(kuò)展袖瞻,而不是使用運(yùn)行時(shí)的方式翔始。
4.閉環(huán)分享是做什么用的贡耽?
答:"閉環(huán)分享=分享出去+拉新回來"就是通過用戶的社交分享行為引導(dǎo)用戶下載App(對(duì)于未安裝App的用戶)太惠,或是在App內(nèi)觀看(對(duì)于已安裝此App的用戶)如暖,讓所有的用戶都能直達(dá)分享內(nèi)容所對(duì)應(yīng)的App頁面爬早,成功把新用戶沉淀下去障涯。
總結(jié):這個(gè)是我簡歷上寫的內(nèi)容较店,面試官問我這個(gè)功能是干什么用的雷客,我答了分享之后再回到app捞奕,面試官問我分享完本來就可以回到app牺堰,是我描述的不夠準(zhǔn)確。應(yīng)該分為未安裝app和已安裝app的用戶分別說明颅围,引導(dǎo)未安裝app的用戶下載app伟葫,已經(jīng)安裝app的用戶在app內(nèi)查看。這個(gè)是一年之前做的一個(gè)需求院促,要求分享app上的一個(gè)頁面到微信筏养,微信上是h5頁面,要求點(diǎn)擊h5頁面上的按鈕可以跳回到app查看常拓。當(dāng)初研究Universal Link的配置還花了很長時(shí)間渐溶,結(jié)果今天問我我什么都沒說出來,讓別人以為不是我做的一樣弄抬。
5.在Xib中一個(gè)ScrollView茎辐,如果內(nèi)容特別多應(yīng)該怎么設(shè)置約束?
答:在ScrollView中增加一個(gè)空白的View掂恕。
總結(jié):這個(gè)是面試官給的答案荔茬,面試官問我如果內(nèi)容特別多超出一屏怎么讓頁面滾動(dòng),我想不起來直接向她請教了竹海。后來我看了一下我的項(xiàng)目中,我確實(shí)是這么做的丐黄,自己做過的東西就是想不起來斋配,只能怪自己下的功夫還是不到位。
6.WKWebView和前端如何進(jìn)行交互,如何改變頁面的高度艰争,如何設(shè)置頁面的背景色坏瞄,用到的語句是什么,在哪個(gè)方法里調(diào)用甩卓?
WKWebView高度自適應(yīng)有三種方式:
1.通過KVO的方式
這種方式獲取的高度較為準(zhǔn)確鸠匀,但要注意表格中多次回調(diào)高度的問題。
添加監(jiān)聽者
#pragma mark ------ < Private Method > ------
#pragma mark
- (void)addWebViewObserver {
[self.wkWebView.scrollView addObserver:self forKeyPath:@"contentSize" options:NSKeyValueObservingOptionNew context:nil];
}
監(jiān)聽高度變化
#pragma mark ------ < KVO > ------
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
/** < 法2 > */
/** < loading:防止?jié)L動(dòng)一直刷新逾柿,出現(xiàn)閃屏 > */
if ([keyPath isEqualToString:@"contentSize"]) {
CGRect webFrame = self.wkWebView.frame;
webFrame.size.height = self.wkWebView.scrollView.contentSize.height;
self.wkWebView.frame = webFrame;
[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObjects:[NSIndexPath indexPathForRow:3 inSection:0], nil] withRowAnimation:UITableViewRowAnimationNone];
}
}
移除觀察者
- (void)removeWebViewObserver {
[self.wkWebView.scrollView removeObserver:self forKeyPath:@"contentSize"];
}
2.通過代理的方式
這種方法通過WKNavigationDelegate代理方法- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation缀棍,網(wǎng)頁加載完成通過JS獲取網(wǎng)頁內(nèi)容高度,但這種方式不一定就是最真實(shí)的高度机错,這時(shí)候可能網(wǎng)頁內(nèi)容還未加載完成爬范,但以實(shí)際情況為準(zhǔn)。
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
[webView evaluateJavaScript:@"document.body.offsetHeight" completionHandler:^(id _Nullable result, NSError * _Nullable error) {
CGFloat documentHeight = [result doubleValue];
CGRect webFrame = webView.frame;
webFrame.size.height = documentHeight;
webView.frame = webFrame;
[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObjects:[NSIndexPath indexPathForRow:3 inSection:0], nil] withRowAnimation:UITableViewRowAnimationNone];
}];
}
3.通過注入JS的方式弱匪,添加網(wǎng)頁加載完成回調(diào)獲取
第三種通常是接口返回HTMLString青瀑,然后自己在APP客戶端成網(wǎng)頁html、head萧诫、body這些標(biāo)簽斥难,在合適的位置加入以下js代碼:
<script type=\"text/javascript\">
window.onload = function() {\
window.location.href = \"ready://\" + document.body.scrollHeight;\
}\
</script>
WKWebView背景色設(shè)置方法:
加載前直接給WKWebView.scrollview設(shè)背景色 加載完成方法里寫設(shè)置背景色的js交互方法:
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
[webView evaluateJavaScript:@"document.body.style.backgroundColor = \"#1E1E1E\"" completionHandler:nil];
}
總結(jié):這些方法的名字我都沒記住,開發(fā)時(shí)用的都是現(xiàn)成的方法帘饶,離開代碼就想不起來了哑诊,以后要鍛煉自己手寫代碼的能力。
7.幀動(dòng)畫圖片占用內(nèi)存過大時(shí)如何解決尖奔?
答:1.創(chuàng)建圖片數(shù)組的時(shí)候用imageWithContentsOfFile而不是imageNamed方法搭儒。
imageNamed:加載到緩存中即使指向他的指針被銷毀了,內(nèi)存中依然會(huì)存在提茁。好處是能快速加載該圖片淹禾,如果這個(gè)圖片經(jīng)常被用到建議此方法。
imageWithContentsOfFile:圖片是不會(huì)緩存的茴扁,如果指向他的指針被銷毀铃岔,內(nèi)存也會(huì)被釋放。這個(gè)方法適合不經(jīng)常使用峭火,或者數(shù)量多的圖片毁习。序列幀的圖片非常適合使用這個(gè)方法。
2.self.imageView.animationImages = nil;//這句話必須不能少卖丸,否則圖片會(huì)釋放不掉的
總結(jié):這道題我按照我平時(shí)項(xiàng)目中的做法答的纺且,使用的是一個(gè)第三方框架,而面試官主要想知道的是如何解決幀動(dòng)畫圖片占用內(nèi)存的問題稍浆,我的回答所答非所問了载碌。
8.TableView嵌套NSTimer卡頓問題如何解決猜嘱?
答:當(dāng)你拖動(dòng)UItableView時(shí),tableView的run loop處于UIEventTrackingRunLoopMode模式嫁艇,在這種模式下朗伶,不處理定時(shí)器事件
因此將NSTimer所在的NSRunLoop修改mode為UITrackingRunLoopMode模式或NSRunLoopCommonModes
[[NSRunLoop currentRunLoop] addTimer:timer forMode:UITrackingRunLoopMode];
或
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
總結(jié):這道題我只回答了用runloop的方法解決,沒答出來具體的方法步咪,這個(gè)例子在平時(shí)開發(fā)中也很常見论皆,應(yīng)該把這幾個(gè)方法記住。
9.Vue傳值都有什么方法猾漫?
1.父組件向子組件傳值
2.子組件向父組件傳值
3.非父子組件傳值
引用官網(wǎng)一句話:父子組件的關(guān)系可以總結(jié)為 prop 向下傳遞点晴,事件向上傳遞。父組件通過 prop 給子組件下發(fā)數(shù)據(jù)静袖,子組件通過事件給父組件發(fā)送消息觉鼻。
總結(jié):今天問了我Vue的東西,因?yàn)槲业暮啔v上寫了队橙,但是前端的面試題還沒看坠陈,也不會(huì)回答,還是先把iOS的面試題弄明白吧捐康。
今日總結(jié):這兩天通過面試題學(xué)到了不少知識(shí)仇矾,收獲很大,找工作的同時(shí)也是深化基礎(chǔ)知識(shí)的機(jī)會(huì)解总,對(duì)以后開發(fā)很有幫助贮匕。我希望通過這一段時(shí)間的面試把iOS的基礎(chǔ)知識(shí)好好過一遍,邊找工作邊學(xué)習(xí)花枫,這兩天面試答的不是太好刻盐,不過面試機(jī)會(huì)還有很多,希望我每一天的面試都有進(jìn)步劳翰。