iOS基础知识(面试必备)
iOS開發(fā)的設(shè)計模式
一、代理模式
應(yīng)用場景:當(dāng)一個類的某些功能需要由別的類來實現(xiàn),但是又不確定具體會是哪個類實現(xiàn)。
優(yōu)勢:解耦合
敏捷原則:開放-封閉原則
實例:tableview的 數(shù)據(jù)源delegate,通過和protocol的配合,完成委托訴求:列表row個數(shù)delegate,自定義的delegate。
二、觀察者模式
應(yīng)用場景:一般為model層對,controller和view進(jìn)行的通知方式,不關(guān)心誰去接收,只負(fù)責(zé)發(fā)布信息。
優(yōu)勢:解耦合
敏捷原則:接口隔離原則,開放-封閉原則
實例:Notification通知中心,注冊通知中心,任何位置可以發(fā)送消息,注冊觀察者的對象可以接收;KVO,鍵值對改變通知的觀察者。
三、MVC模式
應(yīng)用場景:是一中非常古老的設(shè)計模式,通過數(shù)據(jù)模型,控制器邏輯,視圖展示將應(yīng)用程序進(jìn)行邏輯劃分。
優(yōu)勢:使系統(tǒng),層次清晰,職責(zé)分明,易于維護(hù)
敏捷原則:對擴(kuò)展開放-對修改封閉
實例:model-即數(shù)據(jù)模型,view-視圖展示,controller進(jìn)行UI展現(xiàn)和數(shù)據(jù)交互的邏輯控制。
四、單例模式
應(yīng)用場景:確保程序運行期某個類,只有一份實例,用于進(jìn)行資源共享控制。
優(yōu)勢:使用簡單,延時求值,易于跨模塊
敏捷原則:單一職責(zé)原則
實例:[UIApplication sharedApplication]。
注意事項:確保使用者只能通過 getInstance方法才能獲得,單例類的唯一實例。object c中,重寫allocWithZone方法,保證即使用戶用 alloc方法直接創(chuàng)建單例類的實例,返回的也只是此單例類的唯一靜態(tài)變量。
五、策略模式
應(yīng)用場景:定義算法族,封裝起來,使他們之間可以相互替換。
優(yōu)勢:使算法的變化獨立于使用算法的用戶
敏捷原則:接口隔離原則;多用組合,少用繼承;針對接口編程,而非實現(xiàn)。
實例:排序算法,NSArray的sortedArrayUsingSelector;經(jīng)典的鴨子會叫,會飛案例。
注意事項:
1,剝離類中易于變化的行為,通過組合的方式嵌入抽象基類;
2,變化的行為抽象基類為,所有可變變化的父類;
3,用戶類的最終實例,通過注入行為實例的方式,設(shè)定易變行為
防止了繼承行為方式,導(dǎo)致無關(guān)行為污染子類,完成了策略封裝和可替換性。
六、工廠模式
應(yīng)用場景:工廠方式創(chuàng)建類的實例,多與proxy模式配合,創(chuàng)建可替換代理類。
優(yōu)勢:易于替換,面向抽象編程,application只與抽象工廠和易變類的共性抽象類發(fā)生調(diào)用關(guān)系。
敏捷原則:DIP依賴倒置原則
實例:項目部署環(huán)境中依賴多個不同類型的數(shù)據(jù)庫時,需要使用工廠配合proxy完成易用性替換。
注意事項:項目初期,軟件結(jié)構(gòu)和需求都沒有穩(wěn)定下來時,不建議使用此模式,因為其劣勢也很明顯,增加了代碼的復(fù)雜度,增加了調(diào)用層次,增加了內(nèi)存負(fù)擔(dān),所以要注意防止模式的濫用。
delegate與block的區(qū)別
delegate:
1、“一對一”,對同一個協(xié)議,一個對象只能設(shè)置一個代理delegate,所以單例對象就不能用代理;
2、代理更注重過程信息的傳輸:比如發(fā)起一個網(wǎng)絡(luò)請求,可能想要知道此時請求是否已經(jīng)開始、是否收到了數(shù)據(jù)、數(shù)據(jù)是否已經(jīng)接受完成、數(shù)據(jù)接收失敗。
3、公共接口,方法較多選擇用delegate進(jìn)行解耦:iOS有很多例子比如最常用tableViewDelegate,textViewDelegate;
block:
1、寫法更簡練,不需要寫protocol、函數(shù)等;
2、block注重結(jié)果的傳輸:比如對于一個事件,只想知道成功或者失敗,并不需要知道進(jìn)行了多少或者額外的一些信息;
3、異步和簡單的回調(diào)用block更好:iOS有很多例子比如常用的網(wǎng)絡(luò)庫AFNetwork,ASIHTTP庫,UIAlertView類。
4、block需要注意防止循環(huán)引用:
ARC:
非ARC:
__block typeof(self) weakSelf = self;[yourBlock:^(NSArray *repeatedArray, NSArray *incompleteArray) {[weakSelf doSomething];}];補(bǔ)充:
__block和__weak修飾符的區(qū)別:
1.__block不管是ARC還是MRC模式下都可以使用,可以修飾對象,還可以修飾基本數(shù)據(jù)類型。
2.__weak只能在ARC模式下使用,也只能修飾對象(NSString),不能修飾基本數(shù)據(jù)類型(int)。
3.__block對象可以在block中被重新賦值,__weak不可以。
常用的三方庫
1、jsonjson編碼解碼
2、GTMBase64 base64編碼解碼
3、TouchXML 解析
4、SFHFKeychainUtils 安全保存用戶密碼到keychain中
5、MBProgressHUD很棒的一個加載等待特效框架
6、ASIHTTPRequest 等相關(guān)協(xié)議封裝
7、EGORefreshTableHeaderView 下拉刷新代碼
8、AsyncImageView 異步加載圖片并緩存代碼
9、類似setting的豎立也分欄程序
10、MBProgressHUD——進(jìn)展指示符庫
11、Flurry——詳盡的使用統(tǒng)計
12、CorePlot——2D圖形繪圖儀
13、GData client——iPhone上所有Google相關(guān)服務(wù)的類庫
14、SDWebImage——簡化網(wǎng)絡(luò)圖片處理
15、RegexKitLite——正則表達(dá)式支持
網(wǎng)絡(luò)請求GET與POST的區(qū)別
1、GET請求:將參數(shù)直接寫在訪問路徑上,操作簡單, 不過容易讓外界看到, 安全性不高, 地址最多 255 字節(jié);POST 請求: 將參數(shù)放到 body 里面, POST請求的操作相對復(fù)雜, 需要將參數(shù)和地址分開, 不過安全性高,參數(shù)放在body里面, 不容易被捕獲。
2、一個URL地址,它用于描述一個網(wǎng)絡(luò)上的資源,而HTTP中的GET,POST,PUT,DELETE就對應(yīng)著對這個資源的查 ,改 ,增 ,刪 4個操作。因此GET一般用于獲取、查詢資源信息,而POST一般用于更新資源信息。
3、GET使用URL或Cookie傳參,而POST將數(shù)據(jù)放在BODY中。
4、GET的URL會有長度上的限制,則POST的數(shù)據(jù)則可以非常大。
5、POST比GET安全,因為數(shù)據(jù)在地址欄上不可見。
GCD隊列dispatch_queue_t的生成方式
//生成一個串行隊列,隊列中的block按照先進(jìn)先出(FIFO)的順序去執(zhí)行,實際上為單線程執(zhí)行。第一個參數(shù)是隊列的名稱,在調(diào)試程序時會非常有用,所有盡量不要重名了。 dispatch_queue_t queue = dispatch_queue_create("com.dispatch.serial", DISPATCH_QUEUE_SERIAL); //生成一個并發(fā)執(zhí)行隊列,block被分發(fā)到多個線程去執(zhí)行 dispatch_queue_t queue = dispatch_queue_create("com.dispatch.concurrent", DISPATCH_QUEUE_CONCURRENT); //獲得程序進(jìn)程缺省產(chǎn)生的并發(fā)隊列,可設(shè)定優(yōu)先級來選擇高、中、低三個優(yōu)先級隊列。由于是系統(tǒng)默認(rèn)生成的,所以無法調(diào)用dispatch_resume()和dispatch_suspend()來控制執(zhí)行繼續(xù)或中斷。 //需要注意的是,三個隊列不代表三個線程,可能會有更多的線程。并發(fā)隊列可以根據(jù)實際情況來自動產(chǎn)生合理的線程數(shù),也可理解為dispatch隊列實現(xiàn)了一個線程池的管理,對于程序邏輯是透明的。 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); //官網(wǎng)文檔解釋說共有三個并發(fā)隊列,但實際還有一個更低優(yōu)先級的隊列,設(shè)置優(yōu)先級為DISPATCH_QUEUE_PRIORITY_BACKGROUND。Xcode調(diào)試時可以觀察到正在使用的各個dispatch隊列。 dispatch_queue_t queue = dispatch_get_main_queue(); //獲得主線程的dispatch隊列,實際是一個串行隊列。同樣無法控制主線程dispatch隊列的執(zhí)行繼續(xù)或中斷。線程和進(jìn)程的聯(lián)系與區(qū)別
1、進(jìn)程和線程都是由操作系統(tǒng)所體現(xiàn)的程序運行的基本單元,系統(tǒng)利用該基本單元實現(xiàn)系統(tǒng)對應(yīng)用的并發(fā)性(并發(fā)是指兩個或多個任務(wù)在同一時間間隔內(nèi)發(fā)生,但是在任意一個時間點CPU只會處理一個任務(wù)),進(jìn)程是線程的容器,真正完成代碼執(zhí)行的過程,而進(jìn)程則作為線程的執(zhí)行環(huán)境。
2、兩者的主要區(qū)別在于它們是不同的操作系統(tǒng)資源管理方式。進(jìn)程有2立的地址空間,一個進(jìn)程崩潰后,在保護(hù)模式的影響下不會對其他進(jìn)程產(chǎn)生影響,而線程只是一個進(jìn)程中的不同執(zhí)行路徑。線程有自己的堆棧和局部變量,但線程之間沒有單獨的地址空間,一個線程死掉就等同于整個進(jìn)程死掉,所以多進(jìn)程的程序要比多線程的程序健壯,但在進(jìn)程切換時,耗費資源較大,效率要差一些。但對于一些要求同時進(jìn)行并且又要共享某些變量的并發(fā)操作,只能用線程,不能用進(jìn)程。
Block發(fā)生循環(huán)引用和解決方案
發(fā)生情況:定義 block 的時候,會對外部變量做一次copy,而將block屬性設(shè)為了strong, 完成回調(diào)時強(qiáng)引用self。
解決辦法:
// 在ARC下,由于__block抓取的變量一樣會被Block retain,所以必須用弱引用才可以解決循環(huán)引用問題,iOS 5之后可以直接使用__weak,之前則只能使用__unsafe_unretained了,__unsafe_unretained缺點是指針釋放后自己不會置空。__weak typeof(self) weakSelf = self;self.myBlock = ^(int paramInt) {//使用weakSelf訪問self成員[weakSelf doSomething];};//在非ARC下,顯然無法使用弱引用,這里就可以直接使用__block來修飾變量,它不會被Block所retain的。__block typeof(self) weakSelf = self;self.myBlock = ^(int paramInt) {//使用weakSelf訪問self成員[weakSelf doSomething];};用CATextLayer實現(xiàn)一個UILabel
CATextLayer *textLayer = [CATextLayer layer];textLayer.frame = CGRectMake(100,100,100,100);[self.view.layer addSublayer:textLayer];textLayer.foregroundColor = [UIColor blackColor].CGColor;textLayer.alignmentMode = kCAAlignmentJustified;textLayer.wrapped =YES;UIFont *font = [UIFontsystemFontOfSize:15];CFStringRef fontName = (__bridgeCFStringRef)font.fontName;CGFontRef fontRef = CGFontCreateWithFontName(fontName);textLayer.font = fontRef;textLayer.fontSize = font.pointSize;CGFontRelease(fontRef);NSString *text = @"Cupid laid by his brand, and fell asleep";textLayer.string = text;textLayer.contentsScale = [UIScreen mainScreen].scale; // 在Retina顯示參考文章:http://www.jianshu.com/p/7429bb12e10c
Cocoa Touch的框架
Address Book UI 框架:Objective-C的編程接口,可以顯示創(chuàng)建或者編輯聯(lián)系人的標(biāo)準(zhǔn)系統(tǒng)界面。簡化了應(yīng)用程序顯示聯(lián)系人信息所需的工作,也可以確保應(yīng)用程序使用的界面和其他應(yīng)用程序相同,進(jìn)而保證跨平臺一致性。
Game Kit 框架:該框架支持點對點連接及游戲內(nèi)語音功能,您可以通過該框架為應(yīng)用程序增加點對點網(wǎng)絡(luò)功能。
Event Kit UI 框架:提供一個視圖控制鍵可以展現(xiàn)查看并編輯事件的標(biāo)準(zhǔn)系統(tǒng)界面。
iAd 框架:通過該框架在應(yīng)用程序中發(fā)布橫幅廣告,廣告會被放入到標(biāo)準(zhǔn)視圖,您可以將這些視圖加入到用戶界面,并在合適的時機(jī)向用戶展現(xiàn)。這些視圖和蘋果的公告服務(wù)相互協(xié)作,自動處理廣告內(nèi)容的加載和展現(xiàn),同時也可以響應(yīng)用戶對廣告的點擊。
Map Kit 框架:iOS 3.0導(dǎo)入了 Map Kit框架 (MapKit.framework) ,該框架供一個可被嵌入到應(yīng)用程序的地圖界面,該界面包含一個可以滾動的地圖視圖。可以在視圖中添加定制信息,并可將其嵌入到應(yīng)用程序視圖,通過編程的方式設(shè)置地圖的各種屬性(包括當(dāng)前地圖顯示的區(qū)域以及用戶的方位)。也可以使用定制標(biāo)注或標(biāo)準(zhǔn)標(biāo)注(例如使用測針標(biāo)記)突出顯示地圖中的某些區(qū)域或額外的信息。在iOS 4.0系統(tǒng)中,該框架開始支持可拖動標(biāo)注以及定制覆蓋層。可拖動標(biāo)注允許您通過編程方式或通過用戶交互方式重定位某個標(biāo)注的位置。覆蓋層可用于創(chuàng)建多個點組成的復(fù)雜地圖標(biāo)注。地圖表面諸如公交路線、選舉地圖、公園邊界或者氣象信息(例如雷達(dá)數(shù)據(jù))等可以使用覆蓋層進(jìn)行顯示。
Message UI 框架:您可以利用該框架撰寫電子郵件,并將其放入到用戶的發(fā)件箱排隊等候發(fā)送。該框架提供一個視圖控制器界面,您可以在應(yīng)用程序中展現(xiàn)該界面,讓用戶通過該界面撰寫郵件。界面的字段可以根據(jù)待發(fā)送信息的內(nèi)容生成。例如您可以設(shè)置接收人、主題、郵件內(nèi)容并可以在郵件中包含附件。這個界面允許用戶先對郵件進(jìn)行編輯,然后再選擇接受。在用戶接受郵件內(nèi)容后,相應(yīng)的郵件就會放入用戶的發(fā)件箱排隊等候發(fā)送。
UIKit 框架:UIKit框架 (UIKit.framework)的Objective-C編程接口為實現(xiàn)iOS應(yīng)用程序的圖形及事件驅(qū)動提供關(guān)鍵基礎(chǔ)。iOS系統(tǒng)所有程序都需要通過該框架實現(xiàn)下述核心功能:應(yīng)用程序管理,用戶界面管理,圖形和窗口支持,多任務(wù)支持,處理觸摸及移動事件,代表標(biāo)準(zhǔn)系統(tǒng)視圖和控件的對象,文本和web內(nèi)容相關(guān)操作,剪切、復(fù)制以及粘貼,使用動畫顯示用戶界面內(nèi)容,通過URL方式將其他應(yīng)用程序整合到系統(tǒng),蘋果推送通知服務(wù)支持,為殘疾用戶供輔助功能,本地通知的調(diào)度和發(fā)送,創(chuàng)建PDF,使用定制輸入視圖(其行為類似系統(tǒng)鍵盤),創(chuàng)建和系統(tǒng)鍵盤進(jìn)行交互的定制文本視圖。當(dāng)然還有加速器數(shù)據(jù),內(nèi)置相機(jī)(存在相機(jī)的設(shè)備),用戶的圖片庫,設(shè)備名稱和模型信息,電池狀態(tài)信息,距離感應(yīng)器信息,
來自綁定聽筒的遠(yuǎn)程控制信息。媒體層:
1、Core Graphics (也被稱為Quartz),用于處理本地2D向量渲染和圖片渲染。
2、Core Animation ( Quartz Core框架的一部分),為動畫視圖和其他內(nèi)容提供更高級別支持。
3、OpenGL ES,為使用硬件加速接口的2D和3D渲染提供支持。
4、Core Text,提供一個精密的文本布局和渲染引擎。
5、Image I/O,提供讀取及編寫大多數(shù)圖形格式的接口。
6、資產(chǎn)庫框架(Assets Library framework),可用于訪問用戶照片庫中的照片和視頻。音頻技術(shù):
1、媒體播放器框架。該框架可以讓訪問用戶的iTume庫變得很容易,并且支持播放曲目和播放列表。
2、AV Foundation框架。它提供一組簡單易用的Objective-C接口,可用于管理音頻的播放或錄制。.
3、OpenAL框架。它提供一組跨平臺,用于發(fā)布方位音頻的接口。
4、Core Audio框架。它提供的接口簡單而精密,可用于播放或錄制音頻內(nèi)容。您可以使用這些接口播放系統(tǒng)的警報聲音、觸發(fā)備的震動功能、管理多聲道的緩沖和播放、對音頻內(nèi)容進(jìn)行流化處理。視頻技術(shù):
1、媒體播放器框架,它提供一組易于使用的接口,可用于播放應(yīng)用程序中全屏或部分屏的電影。
2、AV Foundation框架,它提供一組Objective-C接口,可以對電影的捕捉和播放進(jìn)行管理。
3、Core Media框架,它對較高級框架使用的底層類型進(jìn)行描述,同時也提供一些底層接口,它們用于對媒體進(jìn)行處理。
#import與@class的區(qū)別
“#import”會將此類的所有文件全部導(dǎo)入,而@class只是告訴編譯器有這么一個類,引用類名,一般用在.h文件@interface之前;簡而言之,就是當(dāng)只需要定義此類時,只需要@class類名即可,而需要用到此類的方法或變量時,就需要用#import來包含整個類的文件;
如果只需要@class ,而用了#import是不會報錯的,但是會大大影響程序的效率,因為這樣在編譯過程中必須將import的所有類都編譯一遍,尤其是引用的類比較多時;比如你在A類中import了B類,而B類中又import了c、d類,那程序在編譯時要將A,B,c,d類全部編譯一遍,而用@class則不會耗費大量時間。
如果有循環(huán)依賴關(guān)系,如:A–>B, B–>A這樣的相互依賴關(guān)系,如果使用#import來相互包含,那么就會出現(xiàn)編譯錯誤,如果使用@class在兩個類的頭文件中相互聲明,則不會有編譯錯誤出現(xiàn)。
如何解決滑動TableView時卡頓的問題
tableView 滑動卡的問題主要是因為:從緩存中或者是從本地讀取圖片給UIImage的時候耗費的時間比較長。需要在子線程中添加:
NSData *imgData = [NSData dataWithContentsOfURL:[NSURL URLWithString:app.icon]]; //得到圖像數(shù)據(jù) UIImage *image = [UIImage imageWithData:imgData];然后在主線程中將image的值賦值給相應(yīng)的imageView.image;
當(dāng)然,這是主要的問題解決,如果想更好地解決,還有最好使用不透明視圖以及不要重復(fù)創(chuàng)建不必要的table cell等優(yōu)化的地方。
UIView的父類與子類
UIButton的父類是UIControl
UIControl的父類是UIView
UIView的父類是 UIResponder
Objective-C中的self和super
當(dāng)使用self調(diào)用方法時,會從當(dāng)前類的方法列表中開始找,如果沒有,就從父類中再找;當(dāng)使用super時,則從父類的方法列表中開始找,然后調(diào)用這個方法。
Objective-C中的copy與retain區(qū)別
copy是內(nèi)容拷貝,對象指向不同的地址,而retain是指針拷貝,指向相同的地址,計數(shù)加1。
Objective-C中的assign與retain的區(qū)別
assign是直接賦值,如果兩個對象共享一內(nèi)存地址,不能直接釋放這塊內(nèi)存地址,否則會引起崩潰現(xiàn)象;當(dāng)數(shù)據(jù)為int、 float等原生類型時,使用assign則不會;
使用retain則可以給上面的內(nèi)存地址分配引用計數(shù),retain引起引用計數(shù)加1,release引起引用計數(shù)減1,當(dāng)引用計數(shù)為0時,dealloc函數(shù)被調(diào)用,內(nèi)存被回收。
Objective-C中的weak與strong的區(qū)別
1、在對象屬性上使用weak 和strong時,strong就相當(dāng)于retain屬性,讓引用計數(shù)+1,而weak相當(dāng)于assign則不會。
2、只有一種情況需要使用weak(默認(rèn)是strong),就是為了避免retain cycles(就是父類中含有子類{父類retain了子類},子類中又調(diào)用了父類{子類又retain了父類},這樣都無法release)
3、聲明為weak的指針,指針指向的地址一旦被釋放,這些指針都將被賦值為nil,這樣的好處能有效的防止野指針。
寫一個NSString類的實現(xiàn)
+ (id)initWithCString:(const char*)nullTerminatedCString encoding:(NSStringEncoding)encoding;+ (id) stringWithCString: (constchar*)nullTerminatedCString encoding: (NSStringEncoding)encoding { NSString *obj; obj = [self allocWithZone:NSDefaultMallocZone()]; obj = [obj initWithCString:nullTerminatedCString encoding: encoding]; return AUTORELEASE(obj); }Objective-C語言的優(yōu)缺點
Objective-C優(yōu)點:
1) Cateogies
2) Posing
3) 動態(tài)識別
4) 指標(biāo)計算
5) 彈性訊息傳遞
6) 不是一個過度復(fù)雜的 C 衍生語言
7) Objective-C 與 C++ 可混合編程
Objective-C缺點:
1) 不支援命名空間
2) 不支持運算符重載
3) 不支持多重繼承
4) 使用動態(tài)運行時類型,所有的方法都是函數(shù)調(diào)用,所以很多編譯時優(yōu)化方法都用不到(如內(nèi)聯(lián)函數(shù)等),性能低劣。
總結(jié)
以上是生活随笔為你收集整理的iOS基础知识(面试必备)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: iOS开发之实现毛玻璃效果及图片模糊效果
- 下一篇: iOS之身份证号码全校验与校验位自动补全