1、有些圖片加載的比較慢怎么處理?怎么優(yōu)化性能?
圖片下載放在異步線程
圖片下載過程中使用占位圖片
如果圖片較大,可以考慮多線程斷點下載
2、單例是怎么實現(xiàn)的
說白了就是一個類不通過alloc方式創(chuàng)建對象,而是用一個靜態(tài)方法返回這個類的對象。系統(tǒng)只需要擁有一個的 全局對象,這樣有利于我們協(xié)調系統(tǒng)整體的行為;
具體代碼怎么寫:dispath_once
怎么保障變量到這只執(zhí)行一次:dispath_once
只保存一份內存地址:用static修飾變量
static的作用:全局的變量只初始化一次,把變量保存在靜態(tài)分區(qū)中,程序從開始運行到結束變量只有一份內存地址
3、代理
自己用的不多,UITableView、UICollectionView這里都用到。把某個對象要做的事情委托給別的對象去做。那么別的對象就是這個對象的代理,代替它來打理要做的事。反映到程序中,首先要明確一個對象的委托方是哪個對象,委托所做的內容是什么。常見的如QQ的自動回復就屬于代 理攔截,代理模式在iphone中得到廣泛應用。
4、用的架構是什么模式?MVC三者之間是怎樣相互通信的,V和C通過什么傳遞?
MVC是一種架構模式,M表示MOdel,V表示視圖View,C表示控制器Controller,Model負責存儲、定義、操作數(shù)據(jù),View用來展示書給用戶,和用戶進行操作交互,Controller是Model和View的協(xié)調者,Controller把Model中的數(shù)據(jù)拿過來給View用。Controller可以直接與Model和View進行通信,而View不能和Controller直接通信。View與Controller通信需要利用代理協(xié)議的方式,Controller遵守代理,實現(xiàn)代理的方法,來監(jiān)聽View的事件。當有數(shù)據(jù)更新時,Model也要與Controller進行通信,這個時候就要用Notification和KVO,這個方式就像一個廣播一樣,Model發(fā)信號,Controller設置監(jiān)聽接受信號,當有數(shù)據(jù)更新時就發(fā)信號給Controller,Model和View不能直接進行通信,這樣會違背MVC設計模式。
5、對觀察者模式的理解
Notification 是觀察者模式的實現(xiàn),KVO是觀察者模式的OB-C底層實現(xiàn)。
NOtification 通過 Notifydcation addobserver 和 remove observer 工作。當一個物體發(fā)生變化時,會通知所有觀察這個物體的觀察者讓其做出反應。實現(xiàn)起來無非就是把所有觀察者的 對象給這個物體,當這個物體的發(fā)生改變,就會調用遍歷所有觀察者的對象調用觀察者的方法從而達到通知觀察者的目的。
KVO(Key-Value- Observing) 是鍵值監(jiān)聽,鍵值觀察機制,提供了觀察某一屬性變化的方法,底層實現(xiàn):當觀察者為一個對象的屬性進行了注冊,被觀察對象的isa指針被修改的時候,isa指針就會指向一個中間類,而不是真實的類。所以 isa指針其實不需要指向實例對象真實的類。所以我們的程序最好不要依賴于isa指針。在調用類的方法的時候,最好要明確對象實例的類名
KVC(Key-Value-Coding)內部的實現(xiàn):KVC是鍵值編碼,是一種間接訪問對象的屬性,使用字符串來標示屬性(例如:setValue:forKey:) ,一個對象在調setValue的時候,(1)首先根據(jù)方法名找到運行方法的時候所需要的環(huán)境參數(shù)。(2)他會從 isa指針結合環(huán)境參數(shù),找到具體的方法實現(xiàn)的接口。(3)再直接查找得來的具體的方法實現(xiàn)。
6、代理和通知的區(qū)別
通知是一對多,代理是一對一
1、效率肯定是delegate比NSNotification高。
2、delegate方法比notification更加直接,需要關注返回值,所以delegate方法往往包含should這個很傳神的詞。相反的,notification最大的特色就是不關心結果。所以notification往往用did這個詞匯。
3、兩個模塊之間聯(lián)系不是很緊密,就用notification傳值,例如多線程之間傳值用notificaiton。
4、delegate只是一種較為簡單的回調,且主要用在一個模塊中,例如底層功能完成了,需要把一些值傳到上層去,就事先把上層的函數(shù)通過delegate傳到底層,然后在底層call這個delegate,它們都在一個模塊中,完成一個功能,例如說 NavgationController 從 B 界面到A 點返回按鈕 (調用popViewController方法) 可以用delegate比較好。
7、第三方框架 MapKit
MapKit蘋果原生框架
8、微信支付和支付寶支付的區(qū)別
9、多線程NSOperation GCD區(qū)別
項目中使用NSOperation的優(yōu)點是NSOperation是對線程的高度抽象,在項目中使用它,會使項目的程序結構更好,子類化NSOperation的設計思路,是具有面向對象的優(yōu)點(復用、封裝),使得實現(xiàn)是多線程支持,而接口簡單,建議在復雜項目中使用。項目中使用GCD的優(yōu)點是GCD本身非常簡單、易用,對于不復雜的多線程操作,會節(jié)省代碼量,而Block參數(shù)的使用,會是代碼更為易讀,建議在簡單項目中使用。
10、block,block在哪種情況下會造成循環(huán)引用,如何解決?
(1) block本質是一個數(shù)據(jù)類型,多用于參數(shù)傳遞,代替代理方法, (有多個參數(shù)需要傳遞或者多個代理方法需要實現(xiàn)還是推薦使用代理方法),少用于當做返回值傳遞. block是一個OC對象,它的功能是保存代碼片段,預先準備好代碼,并在需要的時候執(zhí)行.
(2)因為使用block代碼塊可能會引起內部循壞引用,所以應在block定義前加上修飾
(1)從兩方面分析造成循環(huán)引用問題
當self擁有一個block的時候,在block又調用self的方法(或者self所擁有的某個屬性)。形成你中有我,我中有你,這種時候會造成循環(huán)引用 (你擁有一個對象包含了另外了一個實例變量對象,但是第二個對象又把前一個對象作為它的委托,那么這兩個對象將不會被釋放。)
把某個實例變量變成本地臨時變量,強引用將直接指向這個本地臨時變量,但本地臨時變量一般都會很快釋放,所以一般考慮第一種情況
(2)解決方案:對block進行修飾__weak(arc)或__block(mrc)
11、屬性修飾符copy、strong區(qū)別
OC中NSString為不可變字符串的時候,用copy和strong都是只分配一次內存,但是如果用copy的時候,需要先判斷字符串是否不可變字符串,如果是不可變字符串,就不再分配空間,如果是可變字符串才分配空間。如果程序中用到NSString的地方特別的,每一次都要先進行判斷就會消耗性能,影響用戶體驗,用strong就不會再進行判斷,所以,不可變字符串可以直接用strong。
屬性修飾符weak、strong區(qū)別
weak :弱引用 ,ARC中使用,如果只想的對象被釋放了,其指向nil,可以有效的避免野指針,其引用計數(shù)為1。
strong :強引用,ARC中使用,與MRC中retain類似,使用之后,計數(shù)器+1。
(weak和strong)不同的是 當一個對象不再有strong類型的指針指向它的時候 它會被釋放 ,即使還有weak型指針指向它。
一旦最后一個strong型指針離去 ,這個對象將被釋放,所有剩余的weak型指針都將被清除。
可能有個例子形容是妥當?shù)摹?br>
想象我們的對象是一條狗,狗想要跑掉(被釋放)。
strong型指針就像是栓住的狗。只要你用牽繩掛住狗,狗就不會跑掉。如果有5個人牽著一條狗(5個strong型指針指向1個對象),除非5個牽繩都脫落 ,否著狗是不會跑掉的。
weak型指針就像是一個小孩指著狗喊到:“看!一只狗在那” 只要狗一直被栓著,小孩就能看到狗,(weak指針)會一直指向它。只要狗的牽繩脫落,狗就會跑掉,不管有多少小孩在看著它。
只要最后一個strong型指針不再指向對象,那么對象就會被釋放,同時所有的weak型指針都將會被清除。
弱引用用在哪里
用在block和delegate中
當self擁有一個block的時候,在block又調用self的方法(或者self所擁有的某個屬性)。形成你中有我,我中有你,這種時候會造成循環(huán)引用。
你擁有一個對象包含了另外了一個實例變量對象,但是第二個對象又把前一個對象作為它的委托,那么這兩個對象將不會被釋放。
變量是弱引用的話只能用__weak修飾嗎?還有什么
修飾delegate,即定義一個delegate的屬性時,還可以使用__unsafe_unretain和__weak來修飾,然后通過使用__unsafe_unretain和__weak來單獨標記實例變量。這意味著delegate實例變量將仍然能夠指向第一個對象,但是它不會導致保留第一個對象,因此打破了retain cycle,而能夠釋放兩個對象。
__unsafe_unretain和__weak都能避免retain cycle,但是他們也有一些細微的不同。對于__weak,當釋放指針指向的對象時,該對象的指針將轉換為nil,這是比較安全的行為。而__unsafe_unretain,正如其名稱隱藏的含義,盡管釋放指針指向的對象時,該指針將繼續(xù)指向原來的內存。這將會導致應用crash,所以是unsafe。
為什么我們仍要使用__unsafe_unretain呢?這是因為__weak直到iOS5.0以及l(fā)ion之后才出現(xiàn)。
12、數(shù)據(jù)存儲
四種存儲方式: 1.NSUserDefaults,用于存儲配置信息;2.SQLite,用于存儲查詢需求較多的數(shù)據(jù);3.CoreData,用于規(guī)劃應用中的對象;4.使用基本對象類型定制的個性化緩存方案.
NSUserDefaults:對象中儲存了系統(tǒng)中用戶的配置信息,開發(fā)者可以通過這個實例對象對這些已有的信息進行修改,也可以按照自己的需求創(chuàng)建新的配置項。
SQLite擅長處理的數(shù)據(jù)類型其實與NSUserDefaults差不多,也是基礎類型的小數(shù)據(jù),只是從組織形式上不同。開發(fā)者可 以以關系型數(shù)據(jù)庫的方式組織數(shù)據(jù),使用SQL DML來管理數(shù)據(jù)。一般來說應用中的格式化的文本類數(shù)據(jù)可以存放在數(shù)據(jù)庫 中,尤其是類似聊天記錄、Timeline等這些具有條件查詢和排序需求的數(shù)據(jù)。
CoreData是一個管理方案,它的持久化可以通過SQLite、XML或二進制文件儲存。它可以把整個應用中的對象建模并進 行自動化的管理。從歸檔文件還原模型時CoreData并不是一次性把整個模型中的所有數(shù)據(jù)都載入內存,而是根據(jù)運行時狀態(tài),把被調用到的對象實例載入內存。框架會自動控制這個過程,從而達到控制內存消耗,避免浪費。 無論從設計原理還是使用方法上看,CoreData都比較復雜。因此,如果僅僅是考慮緩存數(shù)據(jù)這個需求,CoreData絕對不 是一個優(yōu)選方案。CoreData的使用場景在于:整個應用使用CoreData規(guī)劃,把應用內的數(shù)據(jù)通過CoreData建模,完全 基于CoreData架構應用。 使用基本對象類型定制的個性化緩存方案:從需求出發(fā)分析緩存數(shù)據(jù)有哪些要求:按Key查找,快速讀取,寫入不影響正常 操作,不浪費內存,支持歸檔。這些都是基本需求,那么再進一步或許還需要固定緩存項數(shù)量,支持隊列緩存,緩存過期 等。
13、CALayer層和UIView的關系
UIView和CALayer是相互依賴的關系。UIView依賴與calayer提供的內容,CALayer依賴uivew提供的容器來顯示繪制的內容。歸根到底CALayer是這一切的基礎,如果沒有CALayer,UIView自身也不會存在,UIView是一個特殊的CALayer實現(xiàn),添加了響應事件的能力。UIView來自CALayer,高于CALayer,是CALayer高層實現(xiàn)與封裝。UIView的所有特性來源于CALayer支持。
14、代碼管理工具git
Git是什么:Git是目前世界上最先進的分布式版本控制系統(tǒng)(沒有之一)。
什么是版本控制系統(tǒng):版本控制是一種記錄一個或若干文件內容變化,以便將來查閱特定版本修訂情況的系統(tǒng)
集中式 vs分布式
CVS及SVN都是集中式的版本控制系統(tǒng),而Git是分布式版本控制系統(tǒng)。
集中式和分布式版本控制系統(tǒng)有什么區(qū)別呢?
集中式版本控制系統(tǒng):版本庫是集中存放在中央服務器的,而干活的時候,用的都是自己的電腦,所以要先從中央服務器取得最新的版本,每個人電腦上都有一個完整的版本庫然后開始干活,干完活了,再把自己的活推送給中央服務器。
分布式版本控制系統(tǒng):每個人的電腦里有完整的版本庫,統(tǒng)通常也有一臺充當“中央服務器”的電腦,但這個服務器的作用僅僅是用來方便“交換”大家的修改,沒有它大家也一樣干活,只是交換修改不方便而已。
15、什么是分支,怎樣創(chuàng)建分支
終端$ git branch testing
我們知道每次我們commit的時候都會生成一個快照,或者說一個版本庫,從引言我們也知道了通過Blob對象存儲文件快照內容,然后Tree對象記錄快照索引目錄,通過索引找到文件快照。
16、runtiem、runloop的實現(xiàn)機制
Runtime:runtime是一套比較底層的純C語言API,屬于1個C語言庫,包含了很多底層的C語言API。在我們平時編寫的OC代碼中,程序運行過程時,其實最終都是轉成了runtime的C語言代碼, runtime算是OC的幕后工作者.
NSRunLoop是iOS的消息機制的處理模式
1、NSRunloop的主要作用:控制runloop里面線程的執(zhí)行和休眠,在有事情做的時候使擋墻NSRunloop控制的線程工作,沒有事情做讓當前runloop的控制線程休眠.
2、runloop就是一直在循環(huán)檢測,從線程start到線程end,檢測inputsourse(如點擊,雙擊等操作)異步時間,檢測timesourse同步事件,見到檢測到輸入源會執(zhí)行處理函數(shù),首先會產生通知,corefunction向線程添加runloop observers來監(jiān)聽事件,意在監(jiān)聽事件發(fā)生時來做處理。
3、runloopmode是一個集合,包括監(jiān)聽:事件源,定時器,以及需通知的runloop observers
runloop在多線程中如何使用
1、只有在為你的程序創(chuàng)建次線程的時候,才需要運行run loop。對于程序的主線程而言,run loop是關鍵部分。Cocoa提供了運行主線程run loop的代碼同時也會自動運行run loop。IOS程序UIApplication中的run方法在程序正常啟動的時候就會啟動run loop。如果你使用xcode提供的模板創(chuàng)建的程序,那你永遠不需要自己去啟動run loop
2、在多線程中,你需要判斷是否需要run loop。如果需要run loop,那么你要負責配置run loop并啟動。你不需要在任何情況下都去啟動run loop。比如,你使用線程去處理一個預先定義好的耗時極長的任務時,你就可以毋需啟動run loop。Run loop只在你要和線程有交互時才需要
17、自動釋放池,如何工作
自動釋放池以棧的形式實現(xiàn):當你創(chuàng)建一個新的自動釋放池時,它將被添加到棧頂.當一個對象收到發(fā)送autorelease消息時,他被添加到當前線程的處于棧頂?shù)淖詣俞尫懦刂?當自動釋放池被回收時,他們從棧中被刪除,并且會給池子里面所有的對象都會做一次release操作。1. ojc-c是通過種"referringcounting"(引計數(shù))的方式來管理內存的, 對象在開始分配內存(alloc)的時候引用計數(shù)為一,以后每當碰到有copy,retain的時候引用計數(shù)都會加一,以后每當碰到release和autorelease的時候引用計數(shù)就會減一,如果此對象的計數(shù)變?yōu)榱?, 就會被系統(tǒng)銷毀.
- NSAutoreleasePool 就是用來做引用計數(shù)的管理工作的,這個東西一般不你管的.
- autorelease和release沒什么區(qū)別,只是引計數(shù)減一的時機不同而已,autorelease會在對象的使用真正結束的時候才做引計數(shù)減一.
18、http和scoket通信的區(qū)別?socket連接相關庫,TCP,UDP的連接方法,HTTP的幾種常用方式?
http和scoket通信的區(qū)別: http是客戶端用http協(xié)議進行請求,發(fā)送請求時候需要封裝http請求頭,并綁定請求的數(shù)據(jù),服務器一般有web服務器配 合(當然也非絕對)。 http請求方式為客戶端主動發(fā)起請求,服務器才能給響應,一次請求完畢后則斷開連接,以節(jié)省資 源。服務器不能主動給客戶端響應(除非采取http長連接技術)。iphone主要使用類是NSUrlConnection。 scoket是客戶端跟服務器直接使用socket“套接字”進行連接,并沒有規(guī)定連接后斷開,所以客戶端和服務器可以保持連 接通道,雙方都可以主動發(fā)送數(shù)據(jù)。一般在游戲開發(fā)或股票開發(fā)這種要求即時性很強并且保持發(fā)送數(shù)據(jù)量比較大的場合使 用。主要使用類是CFSocketRef。
UDP:是用戶數(shù)據(jù)報協(xié)議:主要用在實時性要求高以及對質量相對較弱的地方,但面對現(xiàn)在高質量的線路不是容易丟包除非 是一些擁塞條件下 ,如流媒體
TCP:是傳輸控制協(xié)議:是面連接的,那么運行環(huán)境必然要求其可靠性不可丟包有良好的擁塞控制機制如http ftp telnet 等
http的常用方式:get,post