簡述類目category優點和缺點
優點:
不需要通過增加子類而增加現有類的行為(方法),且類目中的方法與原始類方法基本沒有區別;
通過類目可以將龐大一個類的方法進行劃分,從而便于代碼的日后的維護、更新以及提高代碼的閱讀性;
缺點:
無法向類目添加實例變量,如果需要添加實例變量,只能通過定義子類的方式;
類目中的方法與原始類以及父類方法相比具有更高優先級,如果覆蓋父類的方法,可能導致super消息的斷裂。因此,最好不要覆蓋原始類中的方法。
鍵值編碼KVC
鍵值編碼是一種間接訪問對象的屬性使用字符串來標識屬性,而不是通過調用存取方法,直接或通過實例變量訪問的機制,非對象類型的變量將被自動封裝或者解封成對象,很多情況下會簡化程序代碼;
KVC的缺點:一旦使用 KVC 你的編譯器無法檢查出錯誤,即不會對設置的鍵、鍵路徑進行錯誤檢查,且執行效率要低于合成存取器方法和自定的 setter 和 getter 方法。因為使用 KVC 鍵值編碼,它必須先解析字符串,然后在設置或者訪問對象的實例變量。
鍵值觀察KVO
鍵值觀察機制是一種能使得對象獲取到其他對象屬性變化的通知 ,極大的簡化了代碼。
實現 KVO 鍵值觀察模式,被觀察的對象必須使用 KVC 鍵值編碼來修 改它的實例變量,這樣才能被觀察者觀察到。因此,KVC是KVO的基礎。
KVC機制通過key找到value的原理
當通過KVC調用對象時,比如:[self valueForKey:@”someKey”]時,程序會自動試圖通過下面幾種不同的方式解析這個調用。
首先查找對象是否帶有 someKey 這個方法,如果沒找到,會繼續查找對象是否帶有someKey這個實例變量(iVar),如果還沒有找到,程序會繼續試圖調用 -(id) valueForUndefinedKey:這個方法。如果這個方法還是沒有被實現的話,程序會拋出一個NSUndefinedKeyException異常錯誤。
補充:KVC查找方法的時候,不僅僅會查找someKey這個方法,還會查找getsomeKey這個方法,前面加一個get,或者_someKey以_getsomeKey這幾種形式。同時,查找實例變量的時候也會不僅僅查找someKey這個變量,也會查找_someKey這個變量是否存在。
設計valueForUndefinedKey:方法的主要目的是當你使用-(id)valueForKey方法從對象中請求值時,對象能夠在錯誤發生前,有最后的機會響應這個請求。
#include與#import的區別、#import 與@class 的區別
include 和import其效果相同,都是查詢類中定義的行為(方法);
import不會引起交叉編譯,確保頭文件只會被導入一次;
@class 的表明,只定 義了類的名稱,而具體類的行為是未知的,一般用于.h 文件;
@class 比#import 編譯效率更高。
此外@class 和#import 的主要區別在于解決引用死鎖的問題。
UITableViewCell上有個UILabel,顯示NSTimer實現的秒表時間,手指滾動cell過程中,label是否刷新,為什么?
這是否刷新取決于timer加入到Run Loop中的Mode是什么。Mode主要是用來指定事件在運行循環中的優先級的,分為:
NSDefaultRunLoopMode(kCFRunLoopDefaultMode):默認,空閑狀態
UITrackingRunLoopMode:ScrollView滑動時會切換到該Mode
UIInitializationRunLoopMode:run loop啟動時,會切換到該mode
NSRunLoopCommonModes(kCFRunLoopCommonModes):Mode集合
蘋果公開提供的Mode有兩個:NSDefaultRunLoopMode(kCFRunLoopDefaultMode)
NSRunLoopCommonModes(kCFRunLoopCommonModes)
在編程中:如果我們把一個NSTimer對象以NSDefaultRunLoopMode(kCFRunLoopDefaultMode)添加到主運行循環中的時候, ScrollView滾動過程中會因為mode的切換,而導致NSTimer將不再被調度。當我們滾動的時候,也希望不調度,那就應該使用默認模式。但是,如果希望在滾動時,定時器也要回調,那就應該使用common mode。
對于單元格重用的理解
- 當屏幕上滑出屏幕時,系統會把這個單元格添加到重用隊列中,等待被重用,當有新單元從屏幕外滑入屏幕內時,從重用隊列中找看有沒有可以重用的單元格,若有,就直接用,沒有就重新創建一個。
線程與進程的區別和聯系?
- 一個程序至少要有進城,一個進程至少要有一個線程.
- 進程:資源分配的最小獨立單元,進程是具有一定獨立功能的程序關于某個數據集合上的一次運行活動,進程是系統進行資源分配和調度的一個獨立單位.
- 線程:進程下的一個分支,是進程的實體,是CPU調度和分派的基本單元,它是比進程更小的能獨立運行的基本單位,線程自己基本不擁有系統資源,只擁有一點在運行中必不可少的資源(程序計數器、一組寄存器、棧),但是它可與同屬一個進程的其他線程共享進程所擁有的全部資源。
- 進程和線程都是由操作系統所體會的程序運行的基本單元,系統利用該基本單元實現系統對應用的并發性。
- 進程和線程的主要差別在于它們是不同的操作系統資源管理方式。進程有獨立的地址空間,一個進程崩潰后,在保護模式下不會對其它進程產生影響,而線程只是一個進程中的不同執行路徑。線程有自己的堆棧和局部變量,但線程之間沒有單獨的地址空間,一個線程死掉就等于整個進程死掉,所以多進程的程序要比多線程的程序健壯,但在進程切換時,耗費資源較大,效率要差一些。
但對于一些要求同時進行并且又要共享某些變量的并發操作,只能用線程,不能用進程。
TCP和UDP的區別于聯系
- TCP為傳輸控制層協議,為面向連接、可靠的、點到點的通信;
- UDP為用戶數據報協議,非連接的不可靠的點到多點的通信;
- TCP側重可靠傳輸,UDP側重快速傳輸。
TCP連接的三次握手
- 第一次握手:客戶端發送syn包(syn=j)到服務器,并進入SYN_SEND狀態,等待服務器確認;
- 第二次握手:服務器收到syn包,必須確認客戶的SYN(ack=j+1),同時自己也發送一個SYN包,即SYN+ACK包,此時服務器進入SYN+RECV狀態;
- 第三次握手:客戶端收到服務器的SYN+ACK包,向服務器發送確認包ACK(ack=k+1),此發送完畢,客戶端和服務器進入ESTABLISHED狀態,完成三次狀態。
Scoket連接和HTTP連接的區別:
- HTTP協議是基于TCP連接的,是應用層協議,主要解決如何包裝數據。
- Socket是對TCP/IP協議的封裝,Socket本身并不是協議,而是一個調用接口(API),通過Socket,我們才能使用TCP/IP協議。
- HTTP連接:短連接,客戶端向服務器發送一次請求,服務器響應后連接斷開,節省資源。服務器不能主動給客戶端響應(除非采用HTTP長連接技術),iPhone主要使用類NSURLConnection。
- Socket連接:長連接,客戶端跟服務器端直接使用Socket進行連接,沒有規定連接后斷開,因此客戶端和服務器段保持連接通道,雙方可以主動發送數據,一般多用于游戲.Socket默認連接超時時間是30秒,默認大小是8K(理解為一個數據包大小)。
如何進行真機調試
- 1.首先需要用鑰匙串創建一個鑰匙(key);
- 2.將鑰匙串上傳到官網,獲取iOS Development證書;
- 3.創建App ID即我們應用程序中的Boundle ID;
- 4.添加Device ID即UDID;
- 5.通過勾選前面所創建的證書:App ID、Device ID;
- 6.生成mobileprovision文件;
- 7.先決條件:申請開發者賬號 99美刀
APP發布的上架流程
- 1.登錄應用發布網站添加應用信息;
- 2.下載安裝發布證書;
- 3.選擇發布證書,使用Archive編譯發布包,用Xcode將代碼(發布包)上傳到服務器;
- 4.等待審核通過;
- 5.生成IPA:菜單欄->Product->Archive.
網絡推送通知原理
首先應用發送通知,系統彈出提示框詢問用戶是否允許,當用戶允許后向蘋果服務器(APNS)請求deviceToken,并由蘋果服務器發送給自己的應用,自己的應用將DeviceToken發送自己的服務器,自己服務器想要發送網絡推送時將deviceToken以及想要推送的信息發送給蘋果服務器,蘋果服務器將信息發送給應用。
網絡七層協議
- 應用層:1.用戶接口、應用程序;2.Application典型設備:網關;3.典型協議、標準和應用:TELNET、FTP、HTTP
- 表示層:1.數據表示、壓縮和加密presentation2.典型設備:網關3.典型協議、標準和應用:ASCLL、PICT、TIFF、JPEG|MPEG4.表示層相當于一個東西的表示,表示的一些協議,比如圖片、聲音和視頻MPEG。
- 會話層:1.會話的建立和結束;2.典型設備:網關;3.典型協議、標準和應用:RPC、SQL、NFS、X WINDOWS、ASP
- 傳輸層:1.主要功能:端到端控制Transport;2.典型設備:網關;3.典型協議、標準和應用:TCP、UDP、SPX
- 網絡層:1.主要功能:路由、尋址Network;2.典型設備:路由器;3.典型協議、標準和應用:IP、IPX、APPLETALK、ICMP;
- 數據鏈路層:1.主要功能:保證無差錯的疏忽鏈路的data link;2.典型設備:交換機、網橋、網卡;3.典型協議、標準和應用:802.2、802.3ATM、HDLC、FRAME RELAY;
- 物理層:1.主要功能:傳輸比特流Physical;2.典型設備:集線器、中繼器3.典型協議、標準和應用:V.35、EIA/TIA-232.
對NSUserDefaults的理解
- NSUserDefaults:系統提供的一種存儲數據的方式,主要用于保存少量的數據,默認存儲到library下的Preferences文件夾。
SDWebImage原理
調用類別的方法:
- 從內存中(字典)找圖片(當這個圖片在本次程序加載過),找到直接使用;
- 從沙盒中找,找到直接使用,緩存到內存。
- 從網絡上獲取,使用,緩存到內存,緩存到沙盒。
對于Run Loop的理解
- RunLoop,是多線程的法寶,即一個線程一次只能執行一個任務,執行完任務后就會退出線程。主線程執行完即時任務時會繼續等待接收事件而不退出。非主線程通常來說就是為了執行某一任務的,執行完畢就需要歸還資源,因此默認是不運行RunLoop的;
- 每一個線程都有其對應的RunLoop,只是默認只有主線程的RunLoop是啟動的,其它子線程的RunLoop默認是不啟動的,若要啟動則需要手動啟動;
在一個單獨的線程中,如果需要在處理完某個任務后不退出,繼續等待接收事件,則需要啟用RunLoop; - NSRunLoop提供了一個添加NSTimer的方法,可以指定Mode,如果要讓任何情況下都回調,則需要設置Mode為Common模式;
- 實質上,對于子線程的runloop默認是不存在的,因為蘋果采用了懶加載的方式。如果我們沒有手動調用[NSRunLoop currentRunLoop]的話,就不會去查詢是否存在當前線程的RunLoop,也就不會去加載,更不會創建。
SQLite中常用的SQL語句
- 創建表:creat table 表名 (字段名 字段數據類型 是否為主鍵, 字段名 字段數據類型, 字段名 字段數據類型...);
-
增: insert into 表名 (字段1, 字段2...) values (值1, 值2...);
insert into Strdents (姓名,性別,出生日期) values ('開心朋朋','男','1980/6/15') -
刪: delete from 表名 where 字段 = 值;
delete from a where name='開心朋朋'(刪除表a中列值為開心朋朋的行) -
改:update <表名> set <列名=更新值> [where <更新條件>]
update tongxunlu set 年齡=18 where 姓名='藍色小名' - **查 **:select <列名> from <表名> [where <查詢條件表達試>] [order by <排序的列名>[asc或desc]]
select * from a
內存的使用和優化的注意事項
重用問題:如UITableViewCells、UICollectionViewCells、UITableViewHeaderFooterViews設置正確的reuseIdentifier,充分重用;
盡量把views設置為不透明:當opque為NO的時候,圖層的半透明取決于圖片和其本身合成的圖層為結果,可提高性能;
不要使用太復雜的XIB/Storyboard:載入時就會將XIB/storyboard需要的所有資源,包括圖片全部載入內存,即使未來很久才會使用。那些相比純代碼寫的延遲加載,性能及內存就差了很多;
選擇正確的數據結構:學會選擇對業務場景最合適的數組結構是寫出高效代碼的基礎。比如,數組: 有序的一組值。使用索引來查詢很快,使用值查詢很慢,插入/刪除很慢。字典: 存儲鍵值對,用鍵來查找比較快。集合: 無序的一組值,用值來查找很快,插入/刪除很快。gzip/zip壓縮:當從服務端下載相關附件時,可以通過gzip/zip壓縮后再下載,使得內存更小,下載速度也更快。
延遲加載:對于不應該使用的數據,使用延遲加載方式。對于不需要馬上顯示的視圖,使用延遲加載方式。比如,網絡請求失敗時顯示的提示界面,可能一直都不會使用到,因此應該使用延遲加載。
數據緩存:對于cell的行高要緩存起來,使得reload數據時,效率也極高。而對于那些網絡數據,不需要每次都請求的,應該緩存起來,可以寫入數據庫,也可以通過plist文件存儲。
處理內存警告:一般在基類統一處理內存警告,將相關不用資源立即釋放掉重用大開銷對象:一些objects的初始化很慢,比如NSDateFormatter
和NSCalendar
,但又不可避免地需要使用它們。通常是作為屬性存儲起來,防止反復創建。
避免反復處理數據:許多應用需要從服務器加載功能所需的常為JSON或者XML格式的數據。在服務器端和客戶端使用相同的數據結構很重要;
使用Autorelease Pool:在某些循環創建臨時變量處理數據時,自動釋放池以保證能及時釋放內存;
正確選擇圖片加載方式:詳情閱讀細讀UIImage加載方式
堆和棧的區別
管理方式:
對于棧來講,是由編譯器自動管理,無需我們手工控制;對于堆來說,釋放工作由程序員控制,容易產生memory leak。
申請大小:
棧:棧頂的地址和棧的最大容量是系統預先規定好的,如果申請的空間超過棧的剩余空間時,將提示overflow。因此,能從棧獲得的空間較小。
堆:堆是向高地址擴展的數據結構,是不連續的內存區域。這是由于系統是用鏈表來存儲的空閑內存地址的,自然是不連續的,而鏈表的遍歷方向是由低地址向高地址。堆的大小受限于計算機系統中有效的虛擬內存。由此可見,堆獲得的空間比較靈活,也比較大。
碎片問題:
對于堆來講,頻繁的new/delete勢必會造成內存空間的不連續,從而造成大量的碎片,使程序效率降低。對于棧來講,則不會存在這個問題,因為棧是先進后出的隊列,他們是如此的一一對應,以至于永遠都不可能有一個內存塊從棧中間彈出