標籤:
1.多線程在實際現實中有哪些應用?(網路操作和大量圖片處理不算)
通常耗時的操作都會放在子線程裡處理,然後再回到主線程來顯示。下面舉幾個例子:
- 我們要從資料庫提取資料還要將資料分組後顯示,那麼就會開個子線程來處理,處理完成後才去重新整理UI顯示。
- 拍照後,會在子線程處理圖片,完成後才回到主線程來顯示圖片。拍照出來的圖片太大了,因此要做處理。
- 音頻、視頻處理會在子線程來操作
- 檔案較大時,檔案操作會在子線程中處理
- 做用戶端與服務端資料同步時,會在後台閑時自動同步
2、如果app比較大,怎麼樣減少app的大小?參考答案:
- 將build setting中的Optimization Level設定為Fastest, Smallest [-Os],在發布模式下,預設就是這樣設定的
- 將build setting 中的Strip Debug Symbols During Copy設定為YES,在發布模式下,預設就是這樣設定的
- 資源檔尋找出所有未使用的,去掉這些永遠不會使用的資源檔
- 對嵌入App的音頻進行壓縮處理
3、你在反覆式開發法中是怎麼處理版本相容問題?參考答案:
版本迭代一定要注意相容老版本,比如新增了欄位或者去掉了某些不再使用的欄位,不能引起應用閃退。我們這裡只談程式碼相容新老版本問題,不考慮業務。因為業務是要求後台來相容的,通常介面會有版本號碼控制,用於相容不同版本的用戶端。
對於任何一個App,當可以升級的時候,不會是所有使用者就立刻去升級,通常會有很大一部分的使用者是不願意立刻升級的。原因會有很多種,比如我這種的就不會頻繁升級,因為對於我來說,這個App並不是天天用,沒有必要升級。
那麼,我們在iOS開發時,如何去相容老版本的,保證新版本的增加或者刪減不會影響到老版本呢?其實這個問題似乎並不是說有沒有新、老版本問題,更重要的是程式的健壯性問題。
對於我們做前端的,永遠不要相信後台一定會按照原先約定返回我們想要的資料結構以及所有欄位。
假設介面返回來的資料是這樣的,我們需要通過類型判斷,確保不會因為介面變化返回無效資料而引起閃退。當然,當介面返回的資料結構與我們原先約定的不一樣時,通常是因為後台出錯了,因此為了程式更健壯,我們應該要容得下背景錯誤:
AFHTTPRequestOperation *op = [selfPostRequestWithUrl:urlparams:paramscompletion:^(id responseObject) { BOOL isSuccess = NO; if ([responseObjectisKindOfClass:[NSDictionary class]]) { NSDictionary *response = responseObject[@"response"]; if ([responseisKindOfClass:[NSDictionary class]]) { NSArray *resultList = response[@"resultList"]; if ([resultListisKindOfClass:[NSArray class]]) { NSArray *listModels = [HYBCosmesisModelobjectArrayWithKeyValuesArray:resultList]; isSuccess = YES; completion(listModels); } } } if (!isSuccess) { // 表示出錯 completion(nil); }}errorBlock:^(NSError *error) { errorBlock(error);}];
而我們在使用的時候,對於字串、數組、字典都應該要做一下類型判斷和空處理。比如:
if ([responseisKindOfClass:[NSDictionary class]]) { NSString *value = response[@"blogName"]; if (!kIsEmptyString(value)) { // Do my job } NSArray *array = response[@"array"]; if ([arrayisKindOfClass:[NSArray class]]) { // Do my job }}
對於業務方面的話,由後台來做版本控制,通過在介面做添加公用參數,[email protected]
?要調用的是哪個版本的介面。
4、你和後端伺服器是怎麼進行互動的參考答案:
這個問題非常簡單,但是對於新手就不太清楚了。在很多小公司裡,前端好像什麼都不需要管,只等後台給你一個介面及參數說明就可以了,根本不清楚後端為什麼要這麼設計這個介面。
那筆者也來聊聊如何與後端伺服器互動:
- 在需求確定,定下了開發的周期後,就需要準備開發了。
- iOS、安卓及後端各端主要負責人員在瞭解完需求後,開始分析本期需求需要哪些介面,是否需要新的介面,是否需要改動原有的介面等。在三端統一後,後端介面負責人確定哪天出介面文檔及介面假資料。為什麼要三端一起定介面呢?因為即使是後端介面負責人,也不一定對原有的業務和原有的介面全部都瞭解,任何一方的瞭解加起來才能確定是否可行。
- 如果App還沒有開發過,首先開發一款新的App,那麼iOS、安卓端的架構師,或者主要開發負責人,需要與後端介面負責人共同分析需求,然後初步寫出第一版本介面文檔,然後各方再各自好好看看、分析分析介面是否合理,參數是否合理,結構是否合理等。這資料的結構會決定著整個網路架構的搭建。
好了,就扯談這些吧~
5、怎麼用GCD載入多張圖片之後,把圖片放到融合到一張圖片裡?參考答案:
使用Dispatch Group追加block到Global Group Queue,這些block如果全部執行完畢,就會執行Main Dispatch Queue中的結束處理的block。
當放到group中的所有請求都完成時,才會回調dispatch group notify的block:
dispatch_queue_tqueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);dispatch_group_tgroup = dispatch_group_create();dispatch_group_async(group, queue, ^{ /*載入圖片1 */ });dispatch_group_async(group, queue, ^{ /*載入圖片2 */ });dispatch_group_async(group, queue, ^{ /*載入圖片3 */ }); dispatch_group_notify(group, dispatch_get_main_queue(), ^{ // 合并圖片}); 6、使用GCD的時候,如何在一個group裡添加幾個任務的依賴關係(這幾個任務放在一個組中)參考答案:
這個不太清楚想問什麼,筆者翻看了看GCD中dispatch group t裡,也沒有什麼可以設定同一個組內的任務依賴關係的,就看到dispatch group wait這個API:
longdispatch_group_wait(dispatch_group_tgroup, dispatch_time_ttimeout);
這個API是等待group中的所有任務都執行完畢才能繼續往下執行其它任務。它是同步地等待任務執行完畢。比如,A、B、C、D四個任務,要求A、B執行完畢後,C、D才能開始執行,那麼可以通過這樣做:
dispatch_queue_tqueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);dispatch_group_tgroup = dispatch_group_create(); dispatch_group_async(group, queue, ^{ /* 任務A */ }); dispatch_group_async(group, queue, ^{ /* 任務B */ }); dispatch_group_notify(group, dispatch_get_main_queue(), ^{ dispatch_group_async(group, queue, ^{ /* 任務C */ }); dispatch_group_async(group, queue, ^{ /* 任務D */ });});
或者可以這樣:
dispatch_queue_tqueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);dispatch_group_tgroup = dispatch_group_create(); dispatch_group_async(group, queue, ^{ /* 任務A */ }); dispatch_group_async(group, queue, ^{ /* 任務B */ }); // 同步等待A、B執行dispatch_group_wait(group, DISPATCH_TIME_FOREVER);dispatch_release(group); // 重新建立組group = dispatch_group_create();dispatch_group_async(group, queue, ^{ /* 任務C */ });dispatch_group_async(group, queue, ^{ /* 任務D */ });dispatch_group_notify(group, dispatch_get_main_queue(), ^{ // C、D執行完畢後,想幹嘛就幹嘛去吧});
不知道筆者對題目的理解是否到位,上面的代碼是隨手寫的,可能單詞會寫錯~~~
7 iOS如何在使用者修改頭像後正常顯示
方案一
筆者所能想到的方案:
筆者針對這個問題,第一想到的就是通過圖片的摘要驗證。服務端在介面中返回使用者資訊時,連同圖片的摘要(md5)值也下發到用戶端,然後每次App登入時,服務端都將最新的使用者資訊返回來,用戶端將本地所緩衝的帳戶圖片取出,也產生摘要(md5)五,與服務端所返回來的md5值比較,若相同表示沒有頭像沒有修改過;若不相同,表示頭像已經修改過。
缺點:只要重新登入或者App在後台自動登入後,才能更新。也就是說,如果使用者沒有退出登入,或者沒有到期而不會自動登入,頭像也沒有更新得了。
方案二
在微博上收集到大家的方案。給URL添加一個參數version,當圖片修改之後,URL的version發生變化,那麼就會重新下載圖片來緩衝。
缺點:與方案一類似,要求重新請求資料才能得到最新的URL。
方案三
在修改圖片時,要求不能使用相同的名字,這樣連結路徑是一樣的,但是因為名字不同而找不到。此時,就會重新擷取圖片而不是緩衝的。可以在檔案名稱中帶上首碼進行上傳,譬如avatar-3/v1.jpg,更新後改為avatar-3/v2.jpg。
方案四
用戶端在要求標頭加上If-Modified-Since欄位,表明請求此時間後最新的檔案資源,服務端也會在回應標頭返回這個last-modified欄位表示上次修改時間。
ios面試題目(一)