小知識點

UIButton 與 UITableView 的層級結構

  • 繼承結構,屬于內部的子控件結構
  • UIButton為:UIButton > UIControl > UIView > UIResponder > NSObject
  • UITableView為:UITableView > UIScrollView > UIView > UIResponder > NSObject

設置 ScrollView 的 contentSize 能在 ViewDidLoad 里設置嗎?為什么?

  • 一般情況是可以在 ViewDidLoad 里設置,但是在 autolayout 下,系統(tǒng)會在 ViewDidAppear之前根據 subview 的 constraint 重新計算scrollview 的 contentsize。這就是為什么,在 Viewdidload 里面手動設置了 contentSize 沒用。因為在后面,會再重新計算一次,前面手動設置的值會被覆蓋掉。
  • 解決辦法就是:
    • 去除 autolayout 選項,自己手動設置 contentsize
    • 如果要使用 autolayout,那么自己設置完 subview 的 constraint,然后讓系統(tǒng)自動根據 constraint 計算出 contentsize。要么就在 Viewdidappear 里自己手動設置 contentsize

簡述一下你對 UIView、UIWindow 和 CALayer 的理解

  • UIView:屬于 UIKit.framework 框架,負責渲染矩形區(qū)域內容,為矩形區(qū)添加動畫,響應區(qū)域的觸摸事件,布局和管理一個或多個子視圖。
  • UIWindow:屬于 UIKit.framework 框架,是一個特殊的 UIView,通常在一個程序只會有一個 UIWindow,但可以手動創(chuàng)建多個 UIWindow,同時加到程序里去。UIWindow 在程序中主要起3個作用:
    • 作為容器,包含 app 所要顯示的所有視圖
    • 傳遞觸摸消息到程序的 View 和其他對象
    • 與 UIViewController 協(xié)同工作,方便完成設備方向旋轉的支持
  • CALayer:屬于 QuartzCore.framework,是用來繪制內容的,對內容進行動畫處理依賴與 UIView 來進行顯示,不能處理用戶事件。
  • UIView 和 CALayer 是相互依賴的,UIView 依賴 CALayer 提供內容,CALayer 依賴 UIView 的容器顯示繪制內容。
  • UIViewController:每個視圖控制器都有一個自帶的視圖,并且負責這個視圖相關的一切事務。方便管理視圖中的子視圖,負責 Model 與 View 之間的通信,檢測設備旋轉以及內存警告;是所有視圖控制類的積累,定義了控制器的基本功能

** frame 和 bounds 有什么不同?**

  • frame 指的是:該 View 在父View 坐標系統(tǒng)中的位置和大小(參照是父類的坐標系統(tǒng))
  • bounds 指的是:該 View 在本身坐標系統(tǒng)中的位置和大?。▍⒄拯c事本身坐標系統(tǒng))

關于視圖的聲明周期的問題

  • 首先判斷控制器是否有視圖,如果沒有通過 loadview 方法創(chuàng)建:通過 storyboard 或者代碼
  • 隨后調用 Viewdidload,可以進行下一步的初始化操作,只會被調用一次
  • 在視圖顯示之前調用 Viewwillappear,該函數(shù)可多次調用
  • 在布局變化后,調用 Viewwill、didLayoutSubviews 處理相關信息

響應者鏈條?

  • 事件響應鏈。包括點擊事件,畫面刷新等。在視圖棧內從上至下,或者從下至上傳播,可以說點事件的分發(fā),傳遞以及處理。
  • 響應者鏈
    • UIResponder 類是 UIKit 中一個用于處理事件響應的基類。窗口上的所有事件觸發(fā),都由該類響應(即事件處理入口)。所以,窗口上的 View 及其控制器都是派生于該類的,例如 UIView、UIViewController
    • 調用 UIResponder 類提供的方法或者屬性,我們就可以捕捉到窗口上的所有響應事件,并進行處理。
    • 響應者鏈條是由多個響應者對象連起來的鏈條,其中響應者對象是能處理事件的對象,所有的 View 和 ViewController 都是響應者對象,利用響應者鏈條能讓多個控件處理同一個觸摸事件。
  • 事件傳遞機制
    • 如果當前 View 不能處理當前事件,那么事件將會沿著響應鏈進行傳遞,直到遇到能處理該事件的響應者。

UITableView 的重用機制?

  • 查看 UITableView 頭文件,會找到 NSMutableArray visiableCells,和 NSMutableArray reusableTableCell 兩個結構
  • visiableCells內保存當前顯示的 cells,reusableTableCell保存可重用的 cells
  • tableView 顯示之初,reusableTableCell為空,那么 [tableView dequeueReusabelCellWithIdentifier:cellIdentifier]返回 nil;
  • 開始的 cell 都是通過 init 來創(chuàng)建,而且 cellForRowAtIndexPath 只是調用最大顯示 cell 數(shù)的次數(shù)。比如:有100條數(shù)據,iPhone 一屏最多顯示10個 Cell
  • 程序最開始顯示 tableview 的情況是:
    • 用init 創(chuàng)建10個 cell,并給 cell 指定同樣的重用標識(當然,可以為不同顯示類型的 cell指定不同標識)。并且10個 cell 全部都加入到 visiableCells 數(shù)組,reusableTableCells 為空。
    • 向下拖動 tableview,當 cell 完全移除屏幕,并且 cell11(他也是 alloc 出來的,原因用上)完全顯示出來的時候。cell11加入到 visiableCells,cell11移除 visiableCells,cell11 加入到 reusableTableCells。
    • 接著向下拖動 tableview,因為 reusableTableCells 中已經有值,所以當需要顯示新的 cell,cellForRowAtIndexPath 再次調用的時候,[tableView dequeueReusabelCellWithIdentifier:cellIdentifier]返回 cell。cell1加入到 visiableCells,cell1移除 reusableTableCells;cell2移除 visiableCells,cell2加入到 reusableTableCells。之后再需要顯示的 cell 就可以正常重用了。
    • 注意:配置 cell 的時候一定要注意,對取出的重用 cell 做重新賦值,不要遺留老數(shù)據。

UITableView 的性能優(yōu)化?滑動的時候有種卡的感覺是為什么?怎么解決?

  • 在使用第三方應用時,卻經常遇到性能上的問題,普遍表現(xiàn)在滑動時比較卡,特別是 cell 中包含圖片的情況時。

  • 實際上針對性的優(yōu)化就可以解決 tableview 滑動的時候卡頓的問題:

    • 使用不透明的視圖。不透明視圖可以提高渲染的速度??梢詫?cell 及其子視圖的 opaque 屬性設置為 YES(默認值)。
    • 不要重復創(chuàng)建不必要的 cell。UITableView 只需要一屏幕的 UITableViewCell 的對象即可。因此在 cell 不見的時,可以將其緩存起來,而在需要時繼續(xù)使用它即可。注意:cell 被重用時,需要調用 setNeedsDisplayInRect:或 setNeedsDisplay 方法重繪cell。
    • 減少動畫效果的使用,最好不要使用 insertRowsAtIndexPath:withRowAnimation:方法,而是直接調用 reloadData 方法。
    • 減少視圖的數(shù)目。cell 包含了 textLabel、detailTextLabel 和 imageView 等 View,而你還可以自定義一些視圖放在它contextView 里,創(chuàng)建它會消耗較多的資源,并且也影響渲染的性能。
    • cell 包含圖片,且數(shù)目較多,使用自定義 cell 速度比默認的要快。繼承 UITableViewCell,重寫 drawRect 方法:不過這樣以來,你會發(fā)現(xiàn)選中一行后,這個 cell 就變藍了,其中的內容就被遮擋住了。最簡單的辦法就是將 cell 的 selectionStyle 屬性設置為 None,這樣就不會高亮了。不需要與用戶交互的時候,使用 CALayer,將內容繪制到 layer 上,然后對 cell 的 contextView.layer 調用 addSubLayer方法。這個例子中,layer 并不會顯著影響性能,但如果 layer 透明,或者有圓角、變形等效果,就會影響繪制速度了。解決辦法可以使用預渲染圖像。
    - (void)drawRect:(CGRect)rect {
        
        if (image) {
            [image drawAtPoint:imagePoint];
            self.image = nil;
        } else {
            [placeHolder drawAtPoint:imagePoint];
        }
        
        [text drawInRect:textRect withFont:font lineBreakModel:UILineBreakModelTailTruncation];
    }
    
    • 不要做多余的繪制工作。 在實現(xiàn) drawRect:的時候,它對 rect 參數(shù)就是需要繪制的區(qū)域,這個區(qū)域以外的不需要進行繪制。
    • 預渲染圖像。你會發(fā)現(xiàn)即使做到了上述幾點,當新的圖像出現(xiàn)時,仍然會有短暫的停頓現(xiàn)象。解決的辦法就是在圖形上下文中畫,導出 UIimage 對象,然后再繪制到屏幕。(頭像圓角,或者其他變形的時候,用圖形上下文能提高性能。)異步繪制。
    • 不要阻塞主線程。tableView 在更新數(shù)據的時候,整個界面卡主不動,完全不響應應用的用戶請求。常見的是網絡請求,等待時間長。解決方案:使用多線程,讓子線程去執(zhí)行這些函數(shù)或方法。
    • 注意:當下載線程數(shù)超過2時,會顯著影響主線程的性能所以在不需要響應用戶請求的時,下載線程數(shù)可以增加到5,不建議再加了,以加快下載速度。如果用戶正在交互,應把線程數(shù)量控制在2個以內。
    • 提前計算并緩存好高度。因為 heightForRowAtIndexPath 調用非常頻繁
    • 選中正確的數(shù)據結構:學會選中對業(yè)務場景最適合的數(shù)組結構是寫出高效代碼的基礎。如果,數(shù)組:有序的一組值。使用索引來查詢比較快,使用值查詢很慢,插入、刪除很慢。字典:存儲鍵值對,用鍵查找比較快。集合:無序的一組值,用值來查詢很快,插入、刪除很快。
    • gzip、zip 壓縮:當從服務器下載相關附件時,可以通過 gzip、zip 壓縮后再下載,使得內存更小,下載速度更快。

tableview 的 cell 如何嵌套 collectionView?

  • 思路用網易新聞類似,用自定義的繼承 UITableViewCell 的類,在 initWithFrame 的構造方法中,初始化自定義的繼承自 UICollectionView

下拉和上拉的原理

  • 以 tableView 的上拉刷新為例:
    • 為了進行無縫閱讀,通過 tableView 的代理方法,willDisplayCell 判斷是否是最后一行
    • 如果是最后一行,在顯示最后一行的同時,判斷當前是否存在上拉刷新
    • 如果沒有上拉刷新,就進行加載數(shù)據,啟動小菊花
  • 以 tableView 下拉刷新為例
    • 判斷當前的上拉刷新視圖是否有動畫
    • 如果沒有動畫,就不是上拉刷新
    • 然后下拉刷新加載數(shù)據
    • 加載完畢數(shù)據關閉數(shù)據

如何實現(xiàn) cell 的動態(tài)行高?

  • 如果希望每條數(shù)據顯示自身的高,必須設置兩個屬性,1.預估行高,2.自定義行高
  • 設置預估行高 _tableView.estimatedRowHeight = 200;
  • 設置自定義行高 _tableView.rowHeight = UITableViewAutomaticDimension;
  • 如果讓自定義行高有效,必須讓容器視圖有一個自下而上的約束

談談 webview

  • iOS 開發(fā)中 webview 和 native code 的配合使用的一些經驗和技巧。
  • webview 與運維成本低,更新幾乎不依賴 App 的版本,但在交互和性能上與 native code 有很大的差距。
  • native code 與之對應。
  • h5確實給 web 帶入了一個新時代。這個時代是什么?web App。也就是說,只有脫離 native 的這個前提,在瀏覽器的環(huán)境下,h5的意義才鞥呢顯現(xiàn)

awakeFormNib 與 viewdidload 區(qū)別

  • awakeFromNib:當.nib 文件被加載的時候,會發(fā)送一個 awakeFromNib 消息到 nib 文件中的沒個對象,每個對象都可以定義自己的awakeFromNib函數(shù)來響應這個消息,執(zhí)行必要操作。也就是說 nib 文件創(chuàng)建 View 對象執(zhí)行awakeFromNib
  • viewdiidload:當 View 對象被加載到內存就會執(zhí)行 Viewdidload,不管是通過 nib 還是代碼形式,創(chuàng)建對象就會執(zhí)行 viewdidload

layoutSubview 何時調用?

  • 初始化 init 方法時不會觸發(fā)
  • 滾動 UIScrollView 觸發(fā)
  • 旋轉屏幕觸發(fā)
  • 改變 View 的值觸發(fā),前提是 frame 改變了
  • 改變 UIView 的大小觸發(fā)

viewcontroller 的 didReceiveMemoryWarning在什么時候調用,默認操作是什么?

  • 引用程序收到來自系統(tǒng)的內存警告的時候,調用didReceiveMemoryWarning方法
  • 默認做法:控制器上的 View 不再窗口上顯示時,調用 ViewWillUnload,直接銷毀View,并調用ViewDidUnload

如何實現(xiàn)瀑漂流,流水布局

  • 使用 UICollectionView
  • 使用自定義的 FlowLayout
  • 需要在 layoutAttributeForElementsInRect 中設置自定布局的 item 的 frame
  • 在 prepareLayout 中計算布局
  • 遍歷數(shù)據內容,根據索引取出對應的 attributes(使用 LayoutAttributesForCellWithIndexPath),根據九宮格算法設置布局
  • 細節(jié)1:實際布局,重寫shouldInvalidateLayoutForBoundsChange(bounds 改變從新布局,scrollView 的 contextOffset>bounds)
  • 細節(jié)2:計算設置 itemSize(保證內容顯示完整,UICollectionView 的 context size 是根據 itemsize 計算的)根據列最大高度、對應列數(shù)量求出,最大高度累加得到
  • 細節(jié)3:追加 item 到最短列,避免底部參數(shù)不齊

實現(xiàn)突破輪播圖

  • scrollView 只需要設置三個 imageView 即可,并且默認顯示中間的 imageView
  • 根據 scrollView 的移動情況,迅速變化三個 imageView 中的圖片數(shù)據
  • imageView 更新完畢后,偷偷把 scrollView 拉回到中間的imageView 位置,這樣視覺效果上就實現(xiàn)了無限循環(huán)的效果。

load initialize 方法的區(qū)別

    • (void)load;
      • 當類對象被加入項目時,runtime 會向每個類發(fā)送 load 消息
      • load 方法繪制每個類甚至分類被引入時僅調用一次,調用的順序:父類優(yōu)先于子類,子類優(yōu)先于分類。
      • load 方法不會被類自動繼承
    • (void)initialize;
      • 也是在第一次使用這個類的時候會調用這個方法。

如何播放 gif 圖片,有什么優(yōu)化方案??

  • UIImageView 用來顯示圖片,使用 UIImageView 中的動畫數(shù)組來實現(xiàn)動畫效果
  • 用 UIWebView 來顯示動態(tài)圖片
  • 第三方框架

事件傳遞與響應的過程?

  • 在產生一個事件時,系統(tǒng)會將該事件加入到一個由 UIApplication 管理的事件隊列里去,UIApplication 會從事件隊列中取出最前面的事件,將它傳遞給先發(fā)送事件給應用程序的主窗口。
  • 主窗口會調用 hitTest 方法尋找最適合的視圖控件,找到后會調用控件的 touches 方法來做具體的事情。
  • 當調用 touches 方法,它的默認做法,就會將事件順著響應者鏈條上往上傳遞,傳遞給上一個響應者,接著就會調用上一個響應者的 touches 方法。

有哪些常見的 crash 場景?

  • 訪問了僵尸對象
  • 訪問了不存在的方法
  • 數(shù)組越界
  • 在定時器下一次回調前將定時器釋放掉

LLDB(GDB)常用的調試命令?

  • p 輸出基本類型
  • po 輸出 oc 對象
  • expr 可以在調試中執(zhí)行表達式,并打印結果

如果一個函數(shù)10中有7次正確,3次錯誤,問題可能出現(xiàn)在什么地方?

  • 從函數(shù)的所有條件分支類分析可能的錯誤。
  • 檢測函數(shù)參數(shù)是否存在異常。

如何對 iOS 設備進行性能測試?

  • profile->instruments->Time Profile 進行性能測試
  • App 使用過程中,接聽電話。
  • App 使用過程中,收到推送。
  • 設備充電時,App 的影響以及流暢度。
  • 設備在不同電量(低于10%、50%、95%)時,App 的響應以及流暢度
  • 意外斷電,App 數(shù)據丟失情況。
  • 網絡變化時,App 是如何響應的。
  • 多點觸摸的情況。
  • 跟其他 App 之間進行交互時的響應。
  • 殺死進程在重新打開的反饋
  • iOS 系統(tǒng)語言環(huán)境的變化

AFNetworking 斷點續(xù)傳

  • 斷點續(xù)傳的主要思路:
    • 檢查服務器的文件信息
    • 檢查本地文件
    • 如果比服務器小,斷點續(xù)傳,利用 HTTP 請求頭的 Range實現(xiàn)斷點續(xù)傳
    • 如果比服務器大,重新下載
    • 如何一樣,下載完成

簡單描述一下客戶端的緩存機制?

  • 緩存可以分為:內存數(shù)據緩存、數(shù)據庫緩存、文件緩存
    • 每次想獲取數(shù)據的時候
    • 先檢測內存中有無緩存數(shù)據
    • 在檢測本地有無緩存數(shù)據(數(shù)據庫、文件)
    • 最終發(fā)送網絡請求
    • 將服務器返回的網絡數(shù)據進行緩存(內存、數(shù)據庫、文件)

什么時候序列化和反序列化,用來做什么

  • 序列化把對象轉化為字節(jié)序列的過程
  • 反序列化把直接序列恢復成對象
  • 把文件寫到文件或者數(shù)據庫中,并讀取出來

iOS 中常用的數(shù)據存儲方式有哪些?

  1. 數(shù)據存儲方法:UserDefault、KeyChain、File、DB
  2. file:Plist、Archiver、Stream
  3. DB:Core Data、FFDB
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 37.cocoa內存管理規(guī)則 1)當你使用new,alloc或copy方法創(chuàng)建一個對象時,該對象的保留計數(shù)器值為1...
    如風家的秘密閱讀 887評論 0 4
  • 1.不可變數(shù)組轉變?yōu)榭勺償?shù)組聲明實例變量的數(shù)組 必須記得實現(xiàn) 對于遍歷數(shù)組找到對象后 如果還需要查找 記得先結束 ...
    小新xin閱讀 754評論 0 1
  • 發(fā)現(xiàn) 關注 消息 iOS 第三方庫、插件、知名博客總結 作者大灰狼的小綿羊哥哥關注 2017.06.26 09:4...
    肇東周閱讀 12,241評論 4 61
  • 每個人都有迷失自己的時候,你也曾有吧。 午夜夢回,一顆心茫然失措,不知該去往何處?;叵氚滋?,看看夜晚,仿佛靈魂游離...
    可可豆_4b32閱讀 152評論 0 0
  • 貴州首部商業(yè)微電影《私奔》2016年7月11日在優(yōu)酷網上映。由貴州青年導演黃宗孟執(zhí)導并主演,著名影視明星樊令出品并...
    貴州黃宗孟導演閱讀 510評論 0 0