前言
前幾個月一直在面試,收集一些網(wǎng)上的面試題,整理抄寫,做面試準備,分享給大家.希望大家能夠面試成功!
分別寫出MRC環(huán)境下在assign、retain蟆炊、copy下屬性name對應(yīng)的setter方法的內(nèi)部實現(xiàn).
//assign環(huán)境下
-(void)setName:(NSString *)name{
_name = name;
}
//retain環(huán)境下
-(void)setName:(NSString *)name{
if (_name != name) {
[_name release];
_name = [name retain];
}
}
//copy環(huán)境下
-(void)setName:(NSString *)name{
if (_name != name) {
[_name release];
_name = [name copy];
}
}
ARC環(huán)境下的delloc具體存在的意義在于什么地方?舉例說明具體的s會用場景.
其實在MRC環(huán)境中delloc存在的意義是為了釋放自己的實例變量,移除觀察者,代理置空,停止timer等,但是在ARC環(huán)境下,系統(tǒng)已經(jīng)幫助釋放了該對象所包含的實例對象.當然了像一些Core Foundation對象還是需要自己進行手動釋放的.那么delloc在ARC環(huán)境下的具體作用就是移除觀察者,代理置空,停止timer.
如何看待iOS中的拷貝?
在我看來,我們?nèi)粘OS開發(fā)過程中的拷貝一共有兩種,一種是深拷貝,另外一種則是淺拷貝.
(1)淺拷貝:淺拷貝實際上就是只拷貝指向?qū)ο蟮闹羔?并不會拷貝對象本身,也就是說淺拷貝和原來的指針是指向同一塊內(nèi)存地址的.
(2)深拷貝:深拷貝拷貝的則是對象的本身,所以拷貝前后的兩個指針只想的內(nèi)存地址是不一樣的.
</br>
系統(tǒng)都有哪些單例類?在實際開發(fā)過程中,單例的應(yīng)用場景在于什么地方?
答:系統(tǒng)為我們提供了很多單例類,比如NSUserDefaults、UIApplication、UIScreen霹俺、UIDevice、NSNotificationCenter毒费、NSFileManager等等.而且在實際開發(fā)過程中,除了使用系統(tǒng)給我們提供的單例類之外,還會根據(jù)需求自己創(chuàng)建類.
例如,
1.數(shù)據(jù)庫處理.對于數(shù)據(jù)的增刪改查,可能在很多界面都會用到,那這個時候,我們可以定義一個針對數(shù)據(jù)處理的單例類.
2.音樂播放.在音樂播放類項目,一般在多個頁面都需要音樂播放,所有,我們可以寫一個音樂播放的單例類.
3.下載管理,當下載音樂或者視頻的時候,我們應(yīng)該創(chuàng)建一個單例類來管理下載任務(wù).
4.登錄注冊類,當一個應(yīng)用有登錄注冊的時候,我們應(yīng)給創(chuàng)建一個單例類來管理登錄者的用戶信息和登錄狀態(tài).
程序在啟動的時候主要做了什么操作?
應(yīng)用程序在啟動的時候,會首先執(zhí)行main函數(shù),而在main函數(shù)當中會執(zhí)行UIApplicationMain函數(shù),UIApplicationMain函數(shù)主要做了如下的三個事情.
1.創(chuàng)建并且初始化一個UIApplication對象.
2.創(chuàng)建應(yīng)用程序代理對象,系統(tǒng)默認的是AppDelegate.
3.創(chuàng)建一個事件循環(huán)RunLoop,用來實時監(jiān)測應(yīng)用的各種事件(觸摸,晃動,通知,觀察者,timer等)
簡述ViewController的幾個生命周期.
1.-(instancetype)init
: 初始化方法
2.-(void)loadView
: 加載根式圖
3.-(void)viewDidLoad
: 根式圖已經(jīng)加載完成.
4.-(void)viewWillAppear
: 視圖將要出現(xiàn).
5.-(void)viewDidAppear
:視圖已經(jīng)出現(xiàn).
6.-(void)viewWillDisappear
:視圖將要消失.
7.-(void)viewDidDisappear
:視圖已經(jīng)消失.
8.-(void)delloc
:釋放觀察者,timer關(guān)閉,代理置空.
UIImage初始化一個圖片的方法以及優(yōu)缺點.
UIImage初始化一張圖片最常用的一共有三個方法,分別是是imageNamed:
丙唧、imageWithContentesOfFile:
、imageWithData:
.
(1)imageNamed:
: 這個方法創(chuàng)建的時所需要的圖片是從緩存中獲取的,先在緩存中查找是否有該圖片,如果沒有,那么會將圖片加進緩存中再使用,如果有這張圖片,那么直接使用緩存中的,這個方法創(chuàng)建UIImage對象主要是用于圖片重復(fù)率比較高,當然了,這個方法也是有弊端的,那就是一旦將圖片加入緩存當中,這張圖片就不會被釋放掉了.
(2)imageWithContentesOfFile:
:這個方法是直接從本地沙盒中獲取, 并不會結(jié)果緩存,主要是用于重復(fù)率不是很高的圖片,使用這種方式.
(3)imageWithData:
: 這種方式可以使用本地的網(wǎng)絡(luò)數(shù)據(jù)也可以使用本地的二進制數(shù)據(jù).但是這種方式會造成線程卡頓,所以建議放在子線程中進行實現(xiàn).
block在定義成屬性應(yīng)該用什么關(guān)鍵字?為什么?
block在定義成屬性的時候應(yīng)該使用copy修飾,平常我們使用的block主要是存放在棧區(qū)的(有的也會存放在全局區(qū)).棧區(qū)的block出了作用域之后就會被釋放掉,如果我們在block釋放掉之后還繼續(xù)調(diào)用,那么就會出現(xiàn)crash.理論上,在全局區(qū)的block我們是不需要進行copy的.但是大部分的block是存儲在棧區(qū)的,為了統(tǒng)一規(guī)范管理,所以我們都使用copy對block屬性進行修飾.
談?wù)勀銓lock和delegate的認識.
無論使用block還是delegate本質(zhì)上都是回調(diào).使用block,其優(yōu)勢是回調(diào)的block代碼塊直接放在block賦值位置,使代碼更加緊湊,但是使用block需要注意循環(huán)引用問題,需要使用__weak
和__block
兩個修飾符來解決循環(huán)引用問題;delegate不能像block做特殊處理,但是如果多個對象設(shè)置的代理為一個對象,那么就需要在delegate中判斷一下到底是哪一個對象了.
什么是沙盒?
所謂沙盒就是操作系統(tǒng)為應(yīng)用程序分配的一個文件夾.應(yīng)用程序擁有這個文件夾的訪問權(quán)限,且只能對這個文件夾內(nèi)的文件進行操作.(當然也能訪問系統(tǒng)提供的文件夾,比如相冊),對其他應(yīng)用程序文件夾沒有訪問權(quán)限.
定義屬性的時候,什么情況使用copy蝗罗、assign和retain?
assign用于簡單數(shù)據(jù)類型,如NSInteger、Bool蝌戒、double等.copy和retain用于對象類型,不過copy是用于一個對象可能被修改,但是不想修改原件,所以拷貝一份出來(新拷貝的對象引用計數(shù)為1);這樣新拷貝的修改了,原件不會被修改,同樣,原件被修改了,新拷貝的不會被修改.retain則是引用計數(shù)加1,對象只有一個,并不會進行復(fù)制拷貝.
簡述應(yīng)用程序按Home鍵進入后臺時的生命周期,以及從后臺進入前臺的生命周期.
正在運行的程序點擊Home鍵的時候,程序由活躍狀態(tài)變?yōu)榉腔钴S狀態(tài).之后程序就進入后臺.在這個過程中執(zhí)行了兩個方法分別是applicationWillResigeActive
和applicationDidEnterBackground
.
當程序從后臺進入前臺的時候,應(yīng)用程序由非活躍狀態(tài)變?yōu)榛钴S狀態(tài),這個期間也執(zhí)行了兩個方法分別為applicationWillEnterForeground
和applicationDidBecomeActive
.
在使用一些系統(tǒng)的類例如UITableView時,會發(fā)現(xiàn)其delegate屬性設(shè)置為assign而不是retain,這是為什么?
使用assign而不使用retain的原因在于避免產(chǎn)生循環(huán)引用問題,如果使用retain修飾delegate的話,那么當通過set方式賦值的時候,引用計數(shù)會加1,這樣到最后會造成循環(huán)引用,而assign是直接賦值,并不會引起引用計數(shù)的增加,因此使用assign并不會造成內(nèi)存泄露.
</br>
當手指點擊屏幕上的登錄按鈕,響應(yīng)者鏈的檢測過程是什么樣子的?
當手指觸摸到屏幕上的登錄按鈕,首先runloop檢測到觸摸事件,將事件傳遞給UIApplication對象,UIApplication對象將事件傳遞給AppDelegate對象,AppDelegate對象將事件傳遞給window對象,之后就是rootViewController,接著就是view,之后檢測view上的子視圖,通過比對找到觸摸的Button.
沙盒中一共有幾個文件夾,請簡述它們的作用?
沙盒之中一共有三個文件夾,分別是Documents串塑、Library和Tmp.
Documents : 蘋果建議將程序中建立的或程序中瀏覽的文件數(shù)據(jù)保存到該目錄下,ITunes備份和恢復(fù)時候包含此目錄.
Library : 程序中默認設(shè)置或者是其他狀態(tài)信息.
Library/Caches :存放緩存文件,一般是下載的圖片或視頻,iTunes不會備份此目錄,此目錄不會再在程序退出時刪除.
Tmp : 臨時文件夾,應(yīng)用程序會在重啟的時候,刪除該文件夾下的所有內(nèi)容.
在OC中引入頭文件使用的關(guān)鍵字是哪一個?能在C語言文件中使用嗎?
#import
是OC中引入頭文件所使用的關(guān)鍵字,在C語言中不能使用;#include
是OC和C語言中能引入頭文件共同使用的關(guān)鍵字.
#import
和#include
相比,好處是什么?
使用#import
可以避免重復(fù)導(dǎo)入頭文件問題,而使用#include
需要注意重復(fù)導(dǎo)入問題,因此在OC中都是使用#import
來導(dǎo)入頭文件.
#import <>
和#import " "
相比,區(qū)別是什么?
#import <>
用于系統(tǒng)文件的引用,編譯器會在系統(tǒng)文件目錄查找文件.
#import " "
用于自定義文件的引用,編譯器首先在用戶目錄下查找,接著是安裝目錄,最后是系統(tǒng)目錄.
@class
的作用是什么?
@class
的作用是告訴編譯器@class
后面跟的是一個類名.只是告訴編譯器有這個類名,類中具體還有什么方法并沒有提及,也就說不會導(dǎo)入類中的內(nèi)容.經(jīng)常在頭文件中使用.
多線程的優(yōu)點和缺點分別是什么?
優(yōu)點:1.將耗時較長的事件放在子線程中,防止主線程被卡死.2.可以發(fā)揮多核處理的能力,提高cpu的使用率.
缺點:1.每開辟一個縣城就會造成一定的資源損耗.2.會造成代碼可讀性變差.3.如果出現(xiàn)多個線程訪問一個資源,會造成資源搶奪現(xiàn)象.
NSOperationQueue有一個屬性叫maxConcurrentCount即最大并發(fā)數(shù),這里的最大并發(fā)數(shù)是什么含義?
這里的最大并發(fā)數(shù)是指在隊列中同時執(zhí)行的任務(wù)的個數(shù).
iOS中數(shù)據(jù)持久化都有哪些方式,各有什么特點.iOS平臺如何做數(shù)據(jù)持久化的,CoreData和sqlite有無必然的聯(lián)系?CoreData是一個關(guān)系型數(shù)據(jù)庫嗎?
在iOS中有四種數(shù)據(jù)持久化方式,分別是屬性列表、數(shù)據(jù)歸檔北苟、sqlite3數(shù)據(jù)庫桩匪、CoreData.
CoreData數(shù)據(jù)庫可以使用圖形界面快速定義app的數(shù)據(jù)模型,同時在你的代碼中容易獲取到它.CoreData提供了基礎(chǔ)結(jié)構(gòu)去處理常用的功能.,例如保存,恢復(fù),撤銷和重做.允許你在app中創(chuàng)建新的任務(wù).在使用CoreData數(shù)據(jù)庫的時候,你不需要安裝額外的數(shù)據(jù)庫系統(tǒng),因為CoreData使用內(nèi)置的sqlite數(shù)據(jù)庫.CoreData將你的模型層放入一組在內(nèi)存的數(shù)據(jù)對象中,CoreData會跟中這些對象的變化,同時需要作出相反的變化,例如用戶執(zhí)行撤銷命令.當CoreData在你app數(shù)據(jù)的改變進行保存的時候,CoreData會把這些數(shù)據(jù)歸檔,并永久性保存.
CoreData不是一個關(guān)系型數(shù)據(jù)庫,雖然CoreData執(zhí)行SQLite作為一種存儲類型,但它不能使用任意SQLite數(shù)據(jù)庫.CoreData在使用過程中自己創(chuàng)建這個數(shù)據(jù)庫.CoreData支持一對一、一對多的關(guān)系.
什么是懶加載?在使用懶加載的時候應(yīng)該注意什么?
所謂的懶加載指的是延時創(chuàng)建對象.只有在需要的時候才去創(chuàng)建對象,在真正開發(fā)過程當中,懶加載其實是重寫了getter方法,在getter方法中,實現(xiàn)對象的創(chuàng)建.如果對象為nil的時候才會創(chuàng)建,如果不為nil,直接返回對象.在真正使用懶加載的時候需要使用self.
進行調(diào)用,這樣才能調(diào)用屬性的getter方法.
什么叫RunTime.
Runtime就是運行時,一個程序開發(fā)過程當中通常分為以下幾個階段,編輯-預(yù)編譯-編譯-連接-運行,RunTime就是我們程序在運行階段發(fā)生的一些事情,在這一個階段通常會把OC代碼轉(zhuǎn)化為C代碼,從而提高運行效率.系統(tǒng)給我們提供了runtime的類庫,我們可以通過里面的方法實現(xiàn)OC方法到C函數(shù)的轉(zhuǎn)化,也可以給分類添加屬性.類庫中都有對應(yīng)的方法.
簡單描述一下RunLoop在實際開發(fā)過程中的場景.
比如一個頁面中同時輪播圖和tableView時候,在滑動tableView的時候,輪播圖是不動的.這時候我將輪播圖中的NSTimer加入RunLoop中.
再例如,在一個子線程中開啟另外的一個子線程現(xiàn)在圖片,卻發(fā)現(xiàn)下載任務(wù)并沒有執(zhí)行.這時候需要將下載圖片的任務(wù)代碼放入RunLoop中去.
簡單描述一下SDWebImage的原理和實現(xiàn)機制友鼻,以及SDWebImage的底層實現(xiàn)傻昙。
原理:
1、顯示占位圖彩扔。
2妆档、在內(nèi)存緩存中查找圖片是否已經(jīng)下載,如果現(xiàn)在那么久回調(diào)顯示虫碉。
3贾惦、如果內(nèi)存緩存中沒有,生產(chǎn)NSInvocationOperation添加到隊列中去磁盤中查找敦捧,如果有那么久添加到內(nèi)存中并且回調(diào)顯示须板。
4、如果磁盤中沒有兢卵,那就使用下載器進行下載习瑰,下載完成之后同時在你磁盤中和存緩存中保存并且回調(diào)顯示,寫到文件中也要單獨的使用NSInvocationOperation完成秽荤,避免拖慢主線程甜奄。
5柠横、SDImageCache會在初始化的時候注冊一些消息通知,在內(nèi)存警告或者退到后臺的時候清理內(nèi)存圖片緩存贺嫂,退出程序的時候回清理過期的圖片滓鸠。
實現(xiàn)機制:代理模式
底層實現(xiàn)原理:沙河緩存機制,主要是由(內(nèi)存圖片緩存第喳,內(nèi)存操作緩存糜俗,磁盤沙河緩存)
調(diào)用一個類的靜態(tài)方法需不需要release?
調(diào)用一個雷的靜態(tài)方法不需要ralease曲饱,其實靜態(tài)成員方法也是有對象的悠抹,叫做類對象。膽這個類對象在第一次訪問類成員的時候就會將其加載到內(nèi)存的扩淀,而且該類對象只在程序關(guān)閉的時候才會釋放楔敌,并不需要我們進行管理。
簡述__weak和__block修飾符的區(qū)別驻谆。
1卵凑、__block修飾符不管是在ARC還是MRC環(huán)境下都可以使用,還可以修飾基本數(shù)據(jù)類型胜臊。
2勺卢、__weak只能在ARC環(huán)境下使用,也只能修飾對象象对,不能修飾基本數(shù)據(jù)黑忱。
3、被__block修飾的對象在block中可以重新被賦值勒魔,但是__weak不可以甫煞。
總結(jié)
這邊文章到這里就結(jié)束了,但是我的分享之路還沒有結(jié)束,歡迎繼續(xù)關(guān)注騷棟,謝謝.如果有問題可以探討~