OC中常見基礎知識點彙整

~廢棄回憶 �༄發表於2020-11-20
  • 1.你如何理解OC這門語言的?談一下你對OC的理解?
    • OC語言是C語言的一個超集,只是在C語言的基礎上加上了物件導向的語言特徵,如:繼承,封裝,多型.
    • 封裝:把屬性和方法封裝成一個類,方便我們使用
    • 多型:不同物件對於同一訊息的不同響應,子類可以重寫父類的方法,且允許子類型別的指標賦值給父類型別的指標.
    • OC語言的特點:1.支援類別;2.可與C++混編;
    • OC相比C++相比:1.不支援名稱空間;2.不支援運算子過載;3.不支援多繼承
    • 不支援名稱空間:等價於類的字首;
    • 不支援運算子過載:可以重寫運算子的演算法,實現物件運算;
    • 不支援多繼承:OC中可以使用協議來實現類似多繼承的一個功能.
  • 2.C和OC如何混用,C++和OC如何混用:
    • 實現檔案的副檔名.m改成.mm即可,但cpp檔案必須只能使用c/c++程式碼,而且cpp檔案include的標頭檔案中,也不能出現obj-c的程式碼,因為cpp只能寫C++的程式碼.
  • 3.#include與#import的區別?#import與@Class的區別?
    • #include與#import的區別:#include與#import其效果相同,只是後者不會引起重複匯入,確保標頭檔案只會匯入一次;
    • #import與@class的區別:import是匯入標頭檔案,會把標頭檔案的所有資訊獲取到,這個類有那些變數和方法.而@Class只會告訴編譯器,其後面宣告的名稱是類的名稱,至於這些類是如何定義的,完全不知道,所以即使在標頭檔案中使用了@Class,還是需要在.m中匯入標頭檔案.
    • 注意:使用@Class是為了防止標頭檔案之間相互匯入.
  • 4.你平時是怎麼描述NSString型別的?為什麼用copy?
    • 一個物件呼叫copy方法,是深拷貝還是淺拷貝,由copyZone:方法內的邏輯決定的.
    • 假如一個物件的屬性是NSString型別,而且使用了retain描述,如果把一個NSMutableString的物件賦值給這個屬性.例如:子類的物件可以賦值給父類的指標,屬性內部只是retain了一下,還是指向同一個NSMutableString物件,如果將來在賦值完成之後,再次修改NSMutableString的值,那麼物件的屬性的值也會發生改變,這樣肯定是不對的,所以nsstring型別的屬性一般使用copy,這樣給物件的屬性賦值完成之後,物件的屬性是重新拷貝了一份,就不用害怕外部再修改,即使修改,也不會影響到屬性的值;
    • nonatomic:非原子性,就是多執行緒訪問的時候不加鎖,允許多執行緒同時修改屬性的值;
    • atomic:原子性,就是防止在未完成的時候被另外一個執行緒讀取,造成資料錯誤.
    • 淺拷貝拷貝的是指標,深拷貝拷貝的是物件;
  • 5.assign,retain和copy之間的區別是什麼?作用是什麼?
    • assign:普通賦值,一般基於資料型別,常見委託設計模式,以此來防止迴圈引用;
    • retain:保留計數,獲得了物件的所有權.引用計數在原有的基礎上加1,一般物件型別都是用retain;
    • copy:1>.用來複制物件,一般不可變物件都用copy;2>.還有全域性的block變數;3>.還有就是你需要複製一個物件的時候;
      • 一般不可變物件都用copy:對於系統來說,無論是可變物件還是不可變物件,copy和mutableCopy分別返回不可變物件和可變物件;遵循NSCopying協議可以使用copy,遵循mutableCopying協議可以使用mutableCopy;
      • 還有全域性的block變數:block需要使用copy修飾,從棧移動到堆上,由我們自己管理記憶體,ARC下對於block來說,strong和copy的效果是一樣的.
  • 6.描述一下viewController的生命週期?
    • 當我們呼叫UIViewController的view時;
    • 系統首先判斷當前的UIViewController是否存在view,如果存在就直接返回view;
    • 如果不存在的話,會呼叫loadview的方法(呼叫loadview的時機是:在使用ViewController的view屬性,並且view屬性沒有值的時候呼叫,建立view並賦值給view屬性);
    • 然後判斷loadview方法是否是自定義方法;
    • 如果是自定義方法,就執行自定義方法;
    • 如果不是自定義方法,判斷當前檢視控制器是否有xib,stroyboard;
    • 如果有xib,stroyboard就載入xib,stroyboard;
    • 如果沒有就建立一個空白的view;
    • 呼叫viewDidLoad方法(在viewDidLoad方法執行完畢後呼叫,只要滿足條件,viewDidLoad可有可能多次呼叫);
    • 最後返回view.
  • 7.你什麼時候使用自動釋放池?
    • 建立一個分執行緒的時候,原來不會建立一個自動釋放池,現在可以了,不用寫也行;
    • 區域性大量建立自動釋放物件的時候,可以使用巢狀的自動釋放池,及時釋放區域性自動釋放物件,防止記憶體出現高峰.
    • 防止記憶體出現高峰的方法:
    • 區域性物件用完就釋放;
    • 全域性變數在delloc方法中釋放,切要寫在[super delloc]的上方;
    • 方法內建立的物件,在方法外使用,使用autorelease延遲釋放;
    • 通過靜態方法或者字面量方式建立的物件,使用autorelease.
  • 8.你平時開發程式過程中是如何管理記憶體的?
    • ARC是自動的引用計數,是系統在編譯階段自動的幫助我們在程式碼中加入release,autorelease等記憶體管理程式碼,正因為是在編譯階段加入,所以並不會影響程式的執行效率,反而因為蘋果的優化,相比手動記憶體管理,效率可能會更高,但是使用ARC的時候,有幾個需要注意的問題:
      • 自動釋放(autorelease)是一種延遲釋放機制,在每一個RunLoop結束的時候,自動釋放池就會被銷燬;
      • 自動釋放池本身被銷燬的時候,池子裡面所有的物件都會做一次release操作;
      • 任何OC物件呼叫autorelease方法,就會把物件放在離自己最近的自動釋放池中;
      • 系統預設建立的自動釋放池在方法結束才銷燬;
  • 9.ARC存在記憶體洩露嗎?
    • ARC中如果記憶體管理不當的話,同樣會造成記憶體洩漏,例如:ARC中也會迴圈引用導致記憶體洩漏.OC物件與CoreFoundation類之間橋接時,管理不當也會造成記憶體洩漏.
  • 10.記憶體中堆和棧的區別?
    • 堆(heap),棧(stack)
    • alloc,new,copy的物件建立在堆上面的,需要我們自己負責管理,若程式設計師不釋放,則記憶體就會溢位.棧記憶體一般是由系統自己建立並管理的,例如方法內的指標,形式引數等,系統會把這些變數放到棧中,並在方法結束的時候自動釋放掉.
  • 11.strong和weak的區別?
    • strong是強引用,weak是弱引用,強引用指向的物件不會被釋放;
    • 強引用指向的物件不會被釋放;
    • 弱引用不會對物件的引用計數產生影響;
    • 一個物件沒有被強引用會立刻釋放,弱引用指向的物件在釋放時會自動置空.
  • 12.block的記憶體問題?使用block需要注意什麼?
    • 如果一個block被copy, block會對其中用到的物件retain一次,如果block內部用到了本類的屬性和方法,也會self retain一次,而block如果是全域性的,這個類本身又copy了這個block,這個時候就形成了迴圈引用;
    • 解決迴圈引用:將當前物件賦值給一個區域性變數,並且使用__block關鍵字修飾該區域性變數,使用該區域性變數訪問當前物件的屬性和方法;arc中使用__weak代替.
    • block的三種型別:
      • block內部沒有使用外部變數,是global型別,分配在全域性變數區,是不需要我們自己去管理記憶體的;
      • block內部使用外部變數,是stack型別,分配在棧上面的,也是不需要我們去管理記憶體的;
      • 棧上的block copy到堆上,是malloc型別,是需要我們去管理記憶體的;
  • 13.記憶體不足,系統會發出警告,此時控制器應該如何處理?當記憶體不足的時候你該怎麼處理?
    • 記憶體不足的時候,系統會自動呼叫檢視控制器的didReceiveMemoryWarning方法通知控制器記憶體不足,同時也會傳送一個通知.一般需要在此方法中,釋放掉自己不需要的物件,如記憶體中快取的圖片資料等.
  • 14.你是如何理解單元格重用機制的?
    • 重用機制就是一個容器,使用的是字典的存取方式;key就相當於重用識別符號,value相當於重用的陣列;
    • 當螢幕上單元格滑出螢幕時,系統會把這個單元格新增到重用佇列中,等待被重用,當有新單元格從螢幕外滑入螢幕內時,從重用佇列中找看有沒有可以重用的單元格,如果有,就拿過來用,如果沒有就建立一個來使用.
  • 15.ios中資料儲存有哪些方式?每種儲存方式各有什麼特點?都在什麼場景下使用?
    • 一共四中方式,屬性列表(通過WriteToFile 或者userDefault(偏好設定)存入到Plist檔案),物件序列化(歸檔和解檔),SQLite資料庫,CoreData;
    • 所有的本地持久化資料儲存的本質都是寫檔案,而且只能存到沙盒中;
    • 沙盒機制:就是蘋果的一項安全機制,本質就是系統給每個應用分配了一個資料夾來儲存資料,而且每個應用只能訪問分配給自己的那個資料夾,其他應用的資料夾是不能訪問的;
    • 沙盒中預設有三個資料夾,其中Library資料夾中包括兩個子檔案,分別是Caches和Preferences資料夾:
      • Documents:儲存使用者相關的資料,用來存放不會被清理的資料.(使用者拍攝的視訊,使用者創作的圖片,使用者唱的歌曲,使用者收藏的商品),可以在當中新增子資料夾,iTunes備份和恢復的時候,會包括此目錄。
      • Library/Caches目錄:存放快取檔案,iTunes不會備份此目錄,此目錄下檔案不會在應用退出刪除。一般存放體積比較大,不是特別重要的資源。
      • Library/Preferences目錄:儲存應用的所有偏好設定(偏好設定也就是userDefault),ios的Settings(設定)應用會在該目錄中查詢應用的設定資訊,iTunes會自動備份該目錄
      • tmp:放臨時檔案,不需要永久儲存的,比如下載的時候,需要儲存到臨時檔案中,最終拷貝到Documents或者Library中,iphone重啟後會清空tmp目錄
    • 屬性列表:
      • userDefault(偏好設定)儲存7中資料型別:陣列,字典,字串.NSData,NSDate,NSNumber和Boolean;預設會存在沙盒Library 中的Preference資料夾中一個以bundleIdentifier命名的plist(property list 屬性列表)檔案中.不需要自己再去建立路徑
      • 應用於儲存少量的資料,比如登入的使用者資訊,應用程式配置資訊等.只有陣列,字典,字串,NSData, Boolean可以通過WriteToFile(圖片型別在儲存的時候需要先轉化為NSData型別)進行儲存;依舊是儲存在Plist檔案;
      • Plist檔案中可以儲存的7中資料型別:陣列,字典,字串.NSData,NSDate,NSNumber和Boolean.
    • 物件序列化(也叫做歸檔):
      • 物件序列化最終也是存為屬性列表檔案,如果程式中,需要儲存的時候,直接儲存物件比較方便.例如有一個設定類,我們可以把這個設定類的物件直接儲存,就沒有必要再把裡面的每一個屬性單獨存到檔案中.物件序列化是將一個實現了NSCoding協議的物件,通過序列化(NSKeydArchiver)的形式,將物件中的屬性抽取出來,轉化為二進位制,也就是NSData,可是NSData可以通過另外一種方式就是write to file方式或者儲存到NSUserdefault中.要想使用物件序列化就必須要實現的兩個方法:endcodeWithCoder,initWithCoder.物件序列化的本質就是物件NSData.
      • 物件序列化的本質就是將物件型別轉化為二進位制資料型別;
      • 物件反序列化的本質就是將二進位制資料NSData轉化為物件.
    • SQLite(也叫關係性資料庫)
      • 適合大量,重複,有規律的資料儲存.而且頻繁的讀取,刪除,過濾資料.我們通常使用FMDB第三方
    • CoreData(物件關係對映)
      • 其實就是把物件的屬性和表中的欄位自動對映,簡化程式設計師的負擔,以物件導向的方式運算元據庫.
      • CoreData本質還是資料庫,只不過使用起來更加物件導向,不關注二維的表結構,而是隻需要關注物件,純物件導向的資料操作方式.我們直接使用資料庫的時候,如果向資料庫中插入資料,一般是把一個物件的屬性和資料庫中某個表的欄位一一對應,然後把物件的屬性儲存到具體的表欄位中.取一條資料的時候,把表中的一行資料取出,同樣需要在封裝到物件的屬性中,這樣的方式有點繁瑣,不物件導向.CoreData解決的問題就是不需要這個中間的轉化過程,看起來是直接把物件儲存進去,並且取出,不關心表的存在,實際內部做好了對映關係.
  • 16.如何優化tableview的使用?
    • 複用單元格;
    • 單元格中的檢視儘量都使用不透明的,單元格中儘量少使用動畫;
    • 圖片載入使用非同步載入;
    • 滑動時候不載入圖片,停止滑動的時候載入;
    • 單元格內的內容可以在自定義cell類中的drawRect方法內自己繪製;
    • 如非必要,減少reloadData全部Cell.只reloadRowAtIndexPaths
    • 如果cell是動態行高,計算出高度後快取’
    • cell高度固定的話直接使用cell.rowHeight設定高度;
  • 17.socket和http有什麼區別?
    • socket是網路傳輸層的一種技術,跟http有本質的區別.http是應用層的一個網路協議.使用socket技術理論上來說,按照http的規範,完全可以使用socket來達到傳送http請求的目的,只要傳送的資料包按照http協議來即可.同時http是用來組織資料的,而socket是用來傳送資料的.
    • socket和http的區別:
      • socket是長連線,http是短連線;
      • socket是雙向通訊,http是單向的,只能客戶端向伺服器傳送資料;
      • socket的資料完全由自己組織,http必須按照http協議來傳送.
    • socket使用場景:
      • 客戶端頻繁請求伺服器,如股票應用,需要一直向伺服器請求最新的資料,如果使用http,那麼:第一,就會頻繁連結,造成伺服器巨大壓力,如果使用socket,一次連結,不會消耗伺服器太多資源.第二:頻繁傳送,返回資料,如果使用http,因為http協議的限制,傳送的資料包中包含了很多請求頭,請求行等http協議必須帶的資料,傳送的資料量相比socket大很多,socket只需要請求和返回需要的資料即可,如股票應用中標方,只需要返回股票的最新價格即可,及時性會更高.
      • 客戶端和伺服器相互發資料,如聊天應用,需要客戶端上傳聊天內容,同時,別人給你發訊息,伺服器也能主動把別人傳送的訊息傳送給你.
      • 需要使用socket技術的場景:網路遊戲,即使通訊(一般不自己通過sockets來實現,太過複雜,一般使用第三方平臺,環信,愛萌),股票軟體,自己實現推送機制.
  • 18.什麼是http?http協議的特點?http的資料包有那幾部分組成?GET和POST請求的區別?你還知道有哪些請求方式?Https是什麼?
    • http是超文字傳輸協議,http是應用層的一個網路協議;
    • 特點:
      • 短連線:是客戶端主動傳送請求,伺服器做出響應,伺服器響應之後,連結斷開;
      • 單向連線:伺服器不能主動向客戶端傳送資料.
    • HTTP請求報文:
      • 一個HTTP請求報文由請求行,請求頭,空行和請求資料4個部分組成;
      • 請求行中規定了請求的方式(get/post),請求的url,請求的http協議版本;
      • 請求頭主要是傳遞一些引數,配置一些設定.常見的有rang頭,斷點下載使用,cookie頭,儲存cookie資訊,user-agent,表明客戶端資訊;
      • 請求資料區放置post請求的資料.
    • HTTP響應報文:
      • HTTP響應由三個部分組成,分別是:狀態行,響應頭,響應正文.
      • 狀態行:組成:伺服器協議版本,狀態碼,狀態描述.常見的狀態碼有200(成功),404(url不存在),500(伺服器內部錯誤).一般以2開頭的代表成功,以3開頭的代表重定向,4開頭的代表客戶端錯誤,5開頭的代表伺服器端錯誤.
    • 常見的請求方式的是get,post.但是還有OPTIONS,HEAD,PUT,DELETE,TRACE,但是一般很少用.
    • GET請求:引數在地址後拼接,請求資料區沒有請求資料,不安全(因為所有的引數都拼接在地址後面),不適合傳輸大量資料(長度有限制);
    • POST請求:引數在請求資料區放著,相對Get請求更安全,並且資料大小沒有限制,一般上傳檔案使用.
    • 無論是get,post請求.如果url中有特殊字元,如中文,特殊符號等,需要把url編碼(字串呼叫stringByAddingPercentEncodingWithAllowedCharacters:NSUTF8StringEncoding).
    • https是安全超文字傳輸協議,它是一個安全通訊通道,它基於HTTP開發,用於在客戶端計算和伺服器之間的交換資訊.它使用安全套結字層(SSI)進行資訊交換,簡單來說它是HTTP的安全版.
  • 19.在專案中你處理http通訊常用那種第三方?
    • 在專案中一般都使用ASIHTTPRequest,因為ASIHTTPRequest不再更新,不支援arc.所以現在都使用AFNetworking.目前在IOS9中傳送http請求,需要在info.plist中開啟HTTP請求.
    • ASIHTTPRequest,NSURLConnection是對CFNetwork的封裝,相對更底層.AFNetworking是對NSURLConnection的封裝.ASIHTTPRequest不支援ARC,不再更新,AFNetworking支援ARC,不斷在更新.
    • AFNetworking預設支援的響應頭格式比較少,不支援text/html,而一般伺服器預設返回的型別就是text/html,嚴格來說,如果伺服器返回的是json格式,那麼需要把響應頭中的content-type改為application/json,但是伺服器程式設計師一般都不改,使用預設值,那麼客戶端如果使用AFNetworking,就會出現請求失敗,所以一般使用AFNetworking.manager.responseSerializer.acceptableContentTypes=[NSSet setWithObjects:@“text/html”,nill];需要修改一下這個屬性,讓他支援這個頭.
  • 20.你做專案的時候是如何區分手機網路型別的?
    • 使用蘋果官方的reachability這個類,可以區分手機是否聯網,並且能區分是手機網路還是wifi網路,至於能不能區分2g,3g,4g,應該是不能的,我專案中沒有遇見這種狀況.
  • 21.TCP和UDP有什麼不同?
    • tcp和udp都是網路傳輸層的協議,tcp提供可靠的資料連線,udp提供不可靠的資料連線,不會對資料包的順序,是否丟失進行校驗,如果丟失也不會重新傳送,但是tcp會驗證資料包的順序,丟失還會重新傳送,所以是可靠的.但是udp得優點正是因為少了這些校驗,及時性更好一些,所以常見的視訊聊天,音訊聊天都是用的是udp協議,即使丟失一兩個包,也無妨,最多聲音模糊一下或者畫面稍微卡頓.
    • TCP是面向連線的,一對一的通訊,UDP是廣播方式,一對多的方式.我們使用socket的時候,可以選擇使用tcp或者udp.
    • CP有三次握手,UDP沒有,TCP連線的三次握手:
      • 第一次握手:客戶端傳送syn包到伺服器,並進入SYN_SEND狀態,等待伺服器確認;
      • 第二次握手:伺服器收到syn包,必須確認客戶的SYN,同時自己也傳送一個syn包,即SYN+ACK包,此時伺服器進入SYN+RECV狀態;
      • 第三次握手:客戶端到伺服器的SYN+ACK包,向伺服器傳送確認包ACK,此時傳送完畢,客戶端和伺服器進入established狀態,完成三次握手.完成三次握手後,客戶端和伺服器之間開始傳輸資料.
  • 22.網路七層協議,socket是屬於那一層的,http是屬於那一層的?
    • 應用層,表示層,會話層,傳輸層,網路層,資料鏈層,物理層
    • 應用層:
      • 主要功能:使用者介面,應用程式;
      • application典型裝置:閘道器;
      • 典型協議,標準應和應用:Telnet FTP,HTTP;
      • 我們做應用層,比如我們做軟體,一個視訊播放器,這個就是值一個應用層.
    • 表示層:
      • 主要功能:資料的表示,壓縮和加密presentation
      • 典型裝置:閘道器
      • 典型協議,標準和應用:ASCLL PLCT TIFF JPED MIDI MOEG
      • 表示層相當於一個東西怎麼表示,表示的一些協議,像圖片:JEPG聲音:MDI視訊:MPEG;表示層就是定義這個層的協議的,比如:說某個人說說自己做表示層,可能這個人就是在做MPEG4.
    • 會話層:
      • 主要功能:會話的建立和結束的session;
      • 典型裝置:閘道器;
      • 典型協議,標準和應用:RPC SQL NFS X WINDOWS,ASP;
    • 傳輸層:
      • 主要功能:端到端控制transport;
      • 典型裝置:閘道器;
      • 典型協議,標準和應用:TCP UDP SPX;
    • 網路層:
      • 主要功能:路由,定址network;
      • 典型裝置:路由器;
      • 典型協議,標準和應用:IP IPX APPETALK ICMP
    • 資料鏈路層:
      • 主要功能:保證誤差錯的資料鏈路data link;
      • 典型裝置:交換機,網橋,網路卡;
      • 典型協議,標準和應用:802.2,802.3ATM,HDLC,FRAME RELAY;
    • 物理層:
      • 主要功能傳輸位元流physical;
      • 典型裝置:集線路,中繼器;
      • 典型協議,標準和應用:V.35,EIA/TIA-232
    • socket,tcp,udp屬於傳輸層,http,ftp是屬於應用層.不需要記住每一層的作用,只需要記住名稱即可,而且需要知道,下層為上層提供服務.
  • 23.斷點續傳是如何實現的?
    • 所謂斷點續傳,也就是再次下載的時候,不是下載的時候,不是下載整個檔案內容,而是從已經下載過的資料開始,下載剩下的所有資料.
    • 所以在客戶端給伺服器傳送請求的時候,需要在請求頭加上range頭,bytes=xx-xxx.xx代表需要下載檔案的起始位置,xxx代表結束位置,xxx一般不填,代表從起始位置開始剩下的所有資料.
      • 下載後存放到temp中的檔名=URL進行MD5加密後的結果,既具有唯一性,也不算很長;
      • 使用NSFileHandle向已存在的檔案中追加新的資料,需要保證檔案一定存在,不存在需要先建立一個空的;
      • 使用NSMutableURLRequest中的setvalue:setValue:向請求頭中新增資料;
      • 加入range,下次下載的時候告訴伺服器從哪裡下載.
  • 24.常用的資料組織格式有哪些?你平時是怎麼解析?有哪些資料解析方式?XML和JSON對比,他們有什麼優缺點?
    • XML和JSON
      • 平常我們公司一般公司伺服器返回的資料格式是json,我一般通過系統的NSJSONSerialization來完成解析.之前系統沒有這個類的時候,一般使用第三方庫(JSONKit和SBJSON).
      • XML有兩種解析方式,Dom(讀取全部資料,然後解析)和Sax(邊讀取,邊解析),一般我們都不使用XML這種格式,系統的NSXMLParser可以解析XML,屬於Sax方式.
      • Dom方式是先讀取文件的整個內容,以節點的方式體現出來;
      • Sax方式是流式解析,一點一點讀文件.
    • XML和JSON對比:
      • XML容易讀,但是資料量大;
      • JSON資料量小,目前移動端應用普通採用.
  • 25.類別用的多不多?你都是怎麼用的?都有什麼用?
    • 優點:
      • 不通過繼承的方式為原有的類擴充方法;
      • 分散類的實現;
      • 方法的私有化;
    • 缺點:
      • 只能擴充方法,不能擴充變數;
      • 擴充屬性時,需要自己實現setter和getter方法;
      • 擴充的方法不能和原有的方法重名.
  • 26.類別和擴充套件有什麼區別?
    • 擴充套件在寫法跟類別一致,只是擴充套件的括號中沒有名字,而類別則有;
    • 擴充套件可以新增屬性,變數,但是沒有獨立的.m檔案;而類別則不能.
  • 27.如何清理圖片快取?
    • 呼叫SDWebImageCacher的clear(清楚快取),clean(清除過期快取)方法.
    • 獲取快取檔案的大小:NSInteger Size=[[SDImageCache shareImageCache]getSize];
    • 清理所有的快取:[[SDImageCache shareImageCache]cleanDisk];
  • 28.SDWebImage的實現原理是什麼?
    • 從記憶體(字典)中找圖片(當這個圖片在本次使用程式的過程中已經被載入過),找到直接使用;
    • 從沙盒中找(當這個圖片在之前使用程式的過程中被載入過),找到使用,快取到記憶體中;
    • 從網路上獲取,使用,快取到記憶體,快取到沙盒.
  • 29.IOS中你使用過哪些設計模式,你是怎麼理解的?
    • 單例模式:
      • 全域性只需要一個物件,可以儲存到單例類的屬性中,這樣每個類都可以方便的訪問同一份資料.(比如全域性的設定類,使用者的登入資訊);
      • 一個物件的建立比較消耗資源.
    • 代理模式:
      • 解決類和類之間的事件,傳遞性.把一個類中發生的事件通知到另一個類中,使用代理模式可以降低類和類之間的耦合度;
      • delegate使用assign是防止delegate和self產生迴圈引用;
    • 觀察者(通知,KVO)
      • 代理是一對一,通知是一對多;
      • 代理可以相互傳值,通知只能單向傳值.發通知的物件給接收通知的物件傳值;
      • 通知的效率低於代理(想一想為什麼,通知是需要查詢所有註冊者的資訊的,符合接收條件,才呼叫物件的方法,代理是直接物件呼叫方法.回顧通知和代理的原理,你就懂了).
      • 代理有有線(有線網路)的,通知是無線(wifi)的.
    • 工廠模式
      • 工廠模式解決的問題是多型,一個類可能有多個子類,具體需要那個子類,工廠根據不同的條件返回不同的子類物件.在IOS中類簇就是工廠模式.(使用類簇的類,NSString,NSNumber,NSArray等).
  • 30.MVC是什麼,你對MVC的理解?
    • MVC總體來說解決的問題就是類和類之間的耦合度降低問題,類和類的耦合度降低有利於後期的程式碼修改,程式碼擴充套件,程式碼維護,程式碼排錯.
    • MVC是一種架構模式,M表示資料模型Model,V表示試圖View,C表示控制器Controller.
    • Model負責儲存,定義,運算元據;
    • View用來展示資料給使用者,和使用者進行操作互動;
    • Controller是Model與View的協調者,Controller把Model中的資料拿過來給View用.
    • Controller可以直接與Model和View進行通訊,而View不能和Controller直接通訊.View和Controller通訊需要利用代理協議的方式,當有資料更新時,Model也要與Controller進行通訊,這個時候就用notification和KVO,這個方式就像一個廣播一樣,Model發訊號,Controller設定監聽器接受訊號,當有資料要更新時,就發訊號給Controller.Model和View不能直接進行通訊,因為這樣就違背了MVC的設計思想.
  • 31.你對KVC/KVO的理解?
    • KVC
      • 可以修改只讀屬性和私有變數的值;
      • Key value Coding是cocoa的一個標準組成部分,他能讓我們可以通過name(key)的方法訪問property,不必呼叫明確的property accesser(set/get方法).
      • KVC是一個用於間接訪問物件屬性的機制(一種使用字串而不是訪問器方法去訪問一個物件例項變數的機制).使用該機制不需要呼叫set或者get方法以及來訪問成員變數,它通過setValue:forkey和valueForkey:方法.
      • KVC的機制是啥樣的呢?他是以字串的形式向物件傳送訊息字串是要關注屬性的關鍵.是否存在setter,getter方法.如果不存在,他將在內部查詢名為_key或key的例項變數,如果沒有會呼叫setValueForUndefindedKey:如果也沒有,則會執行報錯;注意是如果是基本資料型別,則需要封裝一下(NSNumber).
    • KVC的使用環境:
      • 無論是property還是普通的全域性屬性變數,都可以用KVC.
    • KVC的優缺點:
      • 優點:主要的好處就是減少程式碼量;沒有property的變數也能通過KVC來設定;
      • 缺點:如果key寫錯時,編譯不會報錯,執行的時候才會報錯.
  • 32.KVO的理解:
    • KVO是一個物件能夠觀察另外一個物件的屬性值,並且能夠發現值的變化.KVO更加適合任何型別的物件傾聽另外一個任意物件的改變,或者是一個物件與另外一個物件保持同步的一種方法,即當另外一種物件的狀態發生改變時,觀察物件馬上作出反應.他只能用來對屬性做出反應,而不會用來對方法或者動作做出反應.
    • KVO的優點:
      • 能夠提供一種簡單的方法實現兩個物件間的同步;
      • 能夠對非我們建立的物件,即內部物件的狀態改變作出響應,而且不需要改變內部物件的現實;
      • 能夠獲得觀察的屬性的屬性的最新值以及先前值;
      • 用key path來觀察屬性,因此也可以觀察巢狀物件(也就是可以觀察一個物件內部物件的屬性的變化,可以無限巢狀)觀察,前提是物件的屬性支援KVO);
      • 完成了對觀察物件的抽象,因為不需要額外的程式碼來允許觀察值能夠被觀察(不需要像通知一樣還需要傳送通知,KVO屬性的改變,外部可以直接觀察).
    • KVO的注意事項:
      • 我們註冊KVO的時候,要觀察那個屬性,在呼叫註冊方法的時候,addObserver:forKey:options:context:forKey處填寫的屬性是以字串形式,萬一屬性名字寫錯,因為是字串,編譯器也不會出現警告以及檢查;
    • KVO的使用:
      • 被觀察者發出addObserver:forKey:options:context:方法來新增觀察者,然後只要被觀察者的keyPath的值變化(注意:單純改變其值不會呼叫次方法,只有通過getters和setters來改變值才會觸發KVO),就會在觀察者裡呼叫方法observerValueForKeyPath:ofObject:change:context:因此觀察者需要實現方法observerValueForKeyPath:ofObject:change:context:來對KVO發出的通知作出響應;
      • 這些程式碼只需要在觀察者裡進行實現,被觀察者不用新增任何程式碼,所以誰要監聽誰註冊,然後對響應進行處理即可,使得觀察者與被觀察者完全解藕,運用很靈活很簡單;但是KVO只能檢測類中的屬性,並且屬性名是通過NSSTring來查詢,編譯器不會幫你查錯和補全,純手敲所以比較容易出錯.
  • 33.多執行緒的實現方式有哪些?並做對比:
    • NSThread:
    • 相當於自己建立一個執行緒,建立執行緒的時候,可以把一個方法放到建立的執行緒中.
      • 優點:NSThread比其他兩個輕量級;
      • 缺點:需要自己管理執行緒的生命週期,執行緒同步,執行緒同步時對資料的加鎖會有一定的系統開銷.
    • NSOperation
    • NSOperation不需要自己建立執行緒,只關注需要線上程中完成的程式碼,然後把NSOperation放到NSOperationQueue中即可,NSOperationQueue會把程式碼放到分執行緒中執行.
    • NSOperation的作用:配合使用NSOperation和NSOperationQueue也能實現多執行緒程式設計.
    • NSOperation和NSOperationQueue實現多執行緒的具體步驟:
    • 先需要執行的操作封裝到一個NSOperation物件中的main方法;
    • 然後將NSOperation物件新增到NSOperationQueue中;
    • 系統會自動將NSOperationQueue中的NSOperation取出來;
    • 將取出的NSOperation封裝的操作放到一個新執行緒中執行;
    • NSOperation的子類:
    • NSOperation是一個抽象類,並不具備操作的能力,必須使用它的子類;
    • 使用NSOperation子類的方式有3種:
      • NSInvocation;在主執行緒中建立方法,則在主執行緒中執行;在分執行緒中建立方法,則在分執行緒中執行;
      • NSBlockOperation;會自動查詢空閒的執行緒進行使用;
      • 自定義類繼承NSOperation,實現內部相應的方法;NSOperation預設是在主執行緒中開啟的.重寫main方法,把子類物件放入NSOperationQueue中,就會自動在分執行緒執行main方法了.
      • 附加:
      • AFNetworking和SDWebimage都是使用來實現非同步的;
      • 當多個執行緒同時修改一個變數的值的時候,需要加鎖,防止混亂.
      • 優點:不需要關心執行緒管理,資料同步的事情,可以把精力放在自己需要執行的操作上.
    • GCD
    • GCD是蘋果公司開發的技術,以優化的應用程式支援多核心處理器和其他的對稱多處理系統的系統.這建立在任務進行執行的執行緒池模式的基礎上的;
    • GCD的佇列是怎麼使用的?通過同步或非同步的方式把任務提交到佇列中;
    • GCD的工作原理:
      • 讓程式平行排隊的特定任務,根據可用的處理資源,安排他們在任何可用的處理器核心上執行任務;
      • 一個任務可以是一個函式或者是一個block.GCD的底層依然是執行緒實現,不過這樣可以讓程式設計師不用關注實現的細節;
      • GCD中必須要使用的是各種佇列,我們通過block,把具體的程式碼放到佇列中,佇列中的任務排隊執行,系統會自動的把佇列中的各個任務分配到具體的執行緒中和cpu中,具體建立多少個執行緒,分配到哪個cpu上,都是由系統管理.
      • GCD中有三種佇列型別:
        • The main queue:系統自帶的一個佇列,放到這個佇列中的程式碼會被系統分配到主執行緒中執行.main queue可以呼叫dispath_main_queue()來獲得.因為main queue是與主執行緒相關的,所以這是一個序列佇列,提交至其中的任務順序執行(一個任務執行完畢以後,在執行下一個任務);
        • Global queues:整個應用程式存在三個全域性佇列(系統已經建立好,只需要獲得即可):高,中(預設),低三個優先順序佇列.可以呼叫dispatch_get_global_queue函式傳入優先順序來訪問佇列.全域性佇列是並行佇列,可以讓多個任務併發(同時)執行(自動開啟多個執行緒r同時執行任務)併發功能只有在非同步函式下有效;
        • 使用者自己建立佇列:dispatch_queue_create建立的佇列,可以是序列的,也可以是並行的,因為系統已經給我們提供了並行,序列佇列,所以一般情況下我們不再需要再建立自己的佇列.使用者建立的佇列可以有任意多個.
        • 注意:分執行緒中不能重新整理UI,重新整理UI只能在主執行緒.如果每個執行緒都可以重新整理UI,將會很容易造成UI衝突,會出現不同步的情況,所以只有主執行緒中能重新整理UI系統是為了降低程式設計的複雜度,最大程度的避免衝突.
    • 分執行緒中回到主執行緒只要有兩種方式:
      • performSeletorOnMainThread;
      • 使用main queue;
    • 分執行緒在使用的時候,有以下幾個需要說明的地方
      • 之前的版本中分執行緒不會自動建立autorelease pool,所以需要在分執行緒建立autorelease pool,目前SDK版本已經不需要了;
      • 如果多個執行緒修改(只是讀取變數,不會有問題)同一個資源,需要注意執行緒同步的問題;
      • timer不能在分執行緒中直接使用,需要手動開啟run loop.
    • 附加:
      • 同步:等待提交的任務執行完畢,才繼續執行當前任務;
      • 非同步:不等待提交的任務執行完畢,繼續執行當前任務;
      • 為什麼需要執行緒?一個執行緒只能執行一個任務,任務耗時較長,那麼後邊的任務都處於等待狀態,所以需要把耗時較長的任務放入到分執行緒執行;
      • 多執行緒是併發執行的;
      • 同步不會產生新的執行緒;
      • 非同步可能會產生新的執行緒;
      • 同步提交到主執行緒會造成或死鎖現象,在主執行緒中執行同步的方式提交任務且阻塞主執行緒.
  • 34.timer的間隔週期準嗎?為什麼?怎麼樣實現一個精準的timer?
    • 定時器timer一般都是準確的,但是當主執行緒有些時候避免會出現堵塞情況,這樣就可能導致定時器timer會延遲從而不準確,使用RunLoop就可以準確了.[NSRunLoop currentRunLoop]addTimer:nil forMode:];
  • 35.如何進行網路推送?推送的流程是什麼?你的推送是怎麼做的?
    • 推送分為本地推送以及網路推送,網路推送APNS分為註冊部分以及推送部分,其中註冊部分分為:
      • 我們的應用(APP)向我們的系統(指的是手機系統)註冊推送;
      • 我們的系統會向使用者詢問是否允許推送;
      • 使用者允許後,我們系統向蘋果系統伺服器索要device token;
      • 蘋果推送伺服器會將device token返回我們客戶端;
      • 我們應用將device token傳送給我們伺服器.
    • 推送部分
      • 我們伺服器將推送的訊息,以及device token傳送給蘋果推送伺服器;
      • 蘋果推送伺服器會將推送的訊息內容傳送給我們客戶端;
    • 推送注意事項:
      • ios7和ios8推送不同;
      • 如果指定推送聲音本地必須有這個檔案,如果聲音為系統預設聲音;
      • 伺服器需要配置cer證書,證書生成時,需要CSR證書籤名請求;
      • 如果使用者選擇不允許推送,那麼無法進行推送;
      • 推送是免費的;
      • 推送是不可靠的,使用者不一定能立即收到該訊息;
      • 推送訊息大小有限制,長度4M.
  • 36.CALayer和UIView之間的區別與聯絡?
    • 每一個UIView都包含一個CALayer物件,CALayer中儲存的是UIView的展示內容資料,負責繪製.UIView管理CALayer,相當於一個管理者,並具備處理觸控事件的能力(因為uiview繼承自uiresponder).
  • 37.核心動畫裡面有哪些常用的動畫類?
    • 常用的動畫類:CABasicAnimation基礎動畫,CAKeyframeAnimation關鍵幀動畫,CAAnimationGroup動畫組,CATransition轉場動畫.
  • 38.常用的手勢有哪些?如何自定義手勢?
    • 系統提供了七種手勢幫我們進行手勢的識別開發:點選UITapGesture,滑動UIPanGestureRecognizer,輕掃UISwipeGestureRecognizer,旋轉UIRotationGestureRecognizer,縮放UIPinchGestureRecognizer,長按UILocalizedIndexedCollation,螢幕邊緣滑動UIScreenEdgePanGestureRecognizer;
  • 39.地圖定位偏移你該怎麼辦?(火星座標)
    • 火星座標系統是一種國家保密處理,其實就是對真實座標系系統進行人為的加偏處理,按照特殊的演算法,將真實的座標加密成虛假的座標,而這個加偏並不是線性的加偏,所以各地的偏移情況都會有所不同.而加密後的座標也常被人稱為火星座標系統.
    • 解決方式一:在GPS軟體中設定一個使用同樣演算法的加偏移功能,即:GPS先從衛星上得到真實座標,然後經過加偏移程式轉換成火星座標,由於是同一個演算法,所以經過軟體加偏移的座標能跟同樣加了偏移的地圖吻合,一般不使用,太麻煩,也不知道轉換演算法,這種方式是專業製作地圖的公司可能會使用;
    • 我們使用第三方t地圖的時候,第三方地圖肯定已經處理過,直接用系統的CALLocationManager獲得座標是真實沒有處理的,但是第三方地圖中,如百度地圖,傳入的座標要經過處理,所以最好的方式就是定位座標的程式碼,和顯示地圖的程式碼使用同一個平臺的程式碼.例如:如果你使用百度地圖,就不要使用CALLocationManager來獲取座標,再傳入百度地圖,這樣地圖就會出現偏移.應該使用BMKLocationService來獲得座標,再傳入百度地圖,這樣才能顯示正確.
  • 40.OC的訊息機制你知道不知道?
    • runtime相當於OC轉換成C的程式碼,可以實現許多OC實現不了的功能或者比較麻煩的功能.例如:為類別新增屬性;
    • 只需要回答,系統內部是靠objc_msgSend來現實方法呼叫的所有的oc方法的呼叫都會編譯為objc_msgSend方法.
  • 41.OC的事件響應者鏈
    • 響應者連結串列示一系列的響應者物件.事件被交由第一響應者物件處理,如果第一響應者不處理,事件被沿著響應者鏈向上傳遞,交給下一個響應者.一般來說,第一響應者是個檢視物件或者其子類物件,當其被觸控後事件被交由其他處理,如果不處理,事件就會被傳遞給它的檢視控制器物件(如果不存在).如果是他的父檢視(superview)物件(如果存在),以此類推,直到頂層檢視.接下來會沿著頂層(top View)到視窗(UIWindow物件)再到程式(UIApplication物件).如果整個過程都沒有響應這個事件,該事件就被丟棄.一般情況下,在響應者鏈中只要由物件處理事件,事件就停止傳遞.但有時候可以在試圖的響應方法中根據一些判斷條件來決定是否需要繼續傳遞事件.
    • 常用UIView的下一個響應者是它的superview,但是當UIView是UIViewController的根試圖的時候,它的下一個響應者就是UIViewController.UIViewController的下一個響應者是其根檢視的superview.依次類推,直到UIWindow.UIWindow不處理UIApplication傳遞給APPDelegate,也不處理,事件就拋棄不再處理,只要有一個響應者處理事件,事件就不再傳遞.
  • 42.常用的資料機構都是有哪些?
    • 資料結構是計算機儲存,組織資料的方式.如陣列,字典都是一種資料結構,他們的組織方式和原理就不一樣.下面說的這些都是比較理論的,在不同的語言中,可能有不同的實現方式,例如在IOS中NSDictionary就是類似hash表的一種結構.
      • 棧:先進後出,相當於一個沒有蓋子的杯子;
      • .佇列:先進先出,相當於一個水管;
      • 二叉搜尋樹;
      • 雜湊表(hash表);
      • 檢索樹(Trie);
      • 優先佇列;
      • 線段樹和樹狀陣列;
      • 字尾樹與字尾陣列;
      • 並查表;
      • 鄰接表和邊表;
      • 資料元素相互之間的關係成為結構.有四類基本結構:集合(元素放在一起相互之間沒有任何關係,例:陣列);線性結構(元素之間存在一一對應的關係,例如:連結串列,棧,佇列);樹形結構(元素之間存在一對多的關係,例如:二叉樹);圖狀結構(元素之間存在多對多的關係,例如:表,導航,z遊戲中的自動尋路);
        • 集合結構:除了同屬於一種型別外,別無其他關係;
        • 線性結構:元素之間存在一對一關係常見型別有:陣列,連結串列,佇列,棧,他們之間在操作上有所區別.例如:連結串列可在任意位置插入或刪除元素,而佇列在隊尾插入元素,隊頭刪除元素,棧只能在棧頂進行插入,刪除操作;
        • 樹形結構:元素之間存在一對多關係,常見型別有:樹(有許多特例:二叉樹,平衡二叉樹,查詢樹等);
        • 圖形結構:元素之間存在多對多關係,圖形結構中每個結點的前驅結點數和後續結點數可以任意多個.
  • 43.如何將產品進行多語言釋出,做國際化開發?
    • 下面是步驟,可以簡潔的回答為,把程式內需要用的字串,寫為多個語言版本,程式內通過NSLocalizedString巨集定義來讀取,系統會根據本機語言,來讀取對應的語言文字.
      • 新建String File檔案,命名為Localizable.strings,往裡面新增你想要的語言支援;
      • 在不同的語言的Localizable.strings檔案中新增對應的文字.
      • XIB國際化.在需要國際化的XIB檔案上新增get Info新增多語言版本,修改個語言版本相應的介面文字及圖片.
      • 程式名稱國際化.新建一個sytring檔案,然後國際化它,get info…
  • 44.OC的RunLoop的應用
    • 目的:是讓你的執行緒在有工作的時候忙於工作,而沒有工作的時候出於休眠狀態.
    • 應用:
      • 提高NSTimer的優先順序;
      • 降低載入圖片的優先順序,滾動tableview不載入圖片;
  • 45.iOS系統的版本比較多,你是如何適配的?
    • 一般可以通過系統的巨集定義或者UIDevice中的systemVersion來判斷系統的版本.如果低版本和高版本中要實現同一個功能,api或者處理流程不一樣,會使用條件編譯來處理,把低版本,高版本的程式碼都寫出來,根據不同的系統版本,選擇性的來編譯不同的程式碼.
  • 46.iOS上應用是如何相容32位系統和64位系統?
    • 在XCode中開啟工程,在Project Setting裡面,把最小應用使用的SDK5.1.1或者更高的版本,把build setting中的Architectures引數設定成"Standard Architectures".這樣你的應用就支援了64位的CPU,再次修復編譯器的錯誤或警告.
    • 注意:修改之後,如果你的程式內使用是int float,那麼可能會存在隱患.因為在64位的系統上,所佔用的位元組數可能跟32位系統上的不一致,最好使用NSInteger來代替int,CGFloat代替float,這樣系統可以自動替換的型別.
    • 應用在相容64位系統後,記憶體的佔用肯定會變多一點(因為安裝包中h包含了32位和64位的兩套指令),不過效能也有相應的提升.
  • 47.如何打包靜態庫?
    • 新建一個Framework&Library的專案,編譯的時候,會將專案中的程式碼檔案打包成一個.a的靜態庫檔案.
    • 編譯的h時候分為device(arm版本)版本和模擬器版本.
  • 48.如果使用svn靜態庫如何提交?
    • 直接提交不上去,一般通過命令列收到提交上去,一般svn工具是預設無法提交.a檔案的.

相關文章