總結一下常見的面試題贮泞,一般初級iOS Developer記住的都是招式楞慈,但招式何其多,面試的時候總會有遺漏和盲區(qū)啃擦,內功心法才是一通萬通囊蓝,能以不變應萬變。這份面試題你答不全不能說明你iOS不及格令蛉,你全答對了你也不能上天聚霜。真正應該關注的是這份題背后所包含的理論知識體系。
內存管理
多線程實現(xiàn)方式
動畫技術
繪圖技術
設計模式
Objective-C的一些語言特性
上點干貨珠叔。
1??. 說說你對ARC和MRC的認識蝎宇?
- ARC:Automatic Reference Counting 自動引用計數(shù)
- MRC:Mannul Reference Counting 手動引用計數(shù)
ARC是基于MRC的,本質都是管理對象的retainCount屬性祷安,不同的是管理內存代碼是由誰來寫姥芥。
MRC要求程序員自己寫代碼管理對象的retainCount屬性,
而在ARC下汇鞭,編譯器編譯代碼的時候凉唐,會自動根據(jù)當前代碼的情況添加對象的內存管理的代碼。
之所以要管理內存霍骄,是因為對象在堆中熊榛,不會自動回收。如果不去管理腕巡,那就要等到程序結束才回收玄坦。如果用戶一直在使用,會導致內存的占用越來越大绘沉。
說到這里煎楣,必須說一下內存管理的原則。
1>對象創(chuàng)建后车伞,要對應一次release
2>哪個指針retain了對象择懂,就用哪個指針release對象
3>retain的次數(shù)要和release相匹配
4>在對象被釋放前,指針不可設為nil或指向別的對象另玖,因為會出現(xiàn)內存泄漏
MRC下要注意的問題:對象之間的循環(huán)retain
ARC下要注意的總是:對象之間的循環(huán)引用
Xcode 4.1之后 才有ARC
ARC下困曙,不顯示指定任何屬性關鍵字時,默認的關鍵字都有哪些谦去?
對應基本數(shù)據(jù)類型默認關鍵字是
atomic,readwrite,assign
對于普通的OC對象
atomic,readwrite,strong
2??. 第三方框架相關
1.談談工作中你是如何做圖片緩存的?
一般用第三方框架SDWebImage
SDWebImage庫的作用:
通過對UIImageView的類別擴展來實現(xiàn)異步加載替換圖片的工作慷丽。
主要用到的對象:
1.UIImageView (WebCache)類別,入口封裝鳄哭,實現(xiàn)讀取圖片完成后的回調要糊。
2.SDWebImageManager,對圖片進行管理的中轉站妆丘,記錄那些圖片正在讀取锄俄。
向下層讀取Cache(調用SDImageCache)局劲,或者向網(wǎng)絡讀取對象( 調用SDWebImageDownloader )。
實現(xiàn)SDImageCache和SDWebImageDownloader的回調奶赠。
3.SDImageCache鱼填,根據(jù)據(jù)URL的MD5摘要對圖片進行存儲和讀取(實現(xiàn)存在內存中或者存在硬盤上兩種實現(xiàn))
實現(xiàn)圖片和內存清理工作毅戈。
4.SDWebImageDownloader剔氏,根據(jù)URL向網(wǎng)絡讀取數(shù)據(jù)(實現(xiàn)部分讀取和全部讀取后再通知回調兩種方式)
5.SDWebImageDecoder,異步對圖像進行了一次解壓.
由于UIImage的imageWithData函數(shù)是每次畫圖的時候才將Data解壓成ARGB的圖像竹祷,
所以在每次畫圖的時候,會有一個解壓操作羊苟,這樣效率很低塑陵,但是只有瞬時的內存需求。
為了提高效率通過SDWebImageDecoder將包裝在Data下的資源解壓蜡励,然后畫在另外一張圖片上令花,這樣這張新圖片就不再需要重復解壓了。
1凉倚、SDImageCache是怎么做數(shù)據(jù)管理的?
SDImageCache分兩個部分兼都,一個是內存層面的,一個是硬盤層面的稽寒。
內存層面的相當是個緩存器扮碧,以Key-Value的形式存儲圖片。當內存不夠的時候會清除所有緩存圖片杏糙。
用搜索文件系統(tǒng)的方式做管理慎王,文件替換方式是以時間為單位,剔除時間大于一周
的圖片文件宏侍。
當SDWebImageManager向SDImageCache要資源時赖淤,先搜索內存層面的數(shù)據(jù),如果有直接返回谅河,沒有的話去訪問磁盤咱旱,將圖片從磁盤讀取出來,然后做Decoder绷耍,將圖片對象放到內存層面做備份吐限,再返回調用層。
2.SDWebImage常見面試題褂始。
1> 圖片文件緩存的時間有多長:1周
_maxCacheAge = kDefaultCacheMaxCacheAge
2> SDWebImage 的內存緩存是用什么實現(xiàn)的毯盈?
NSCache
3> SDWebImage 的最大并發(fā)數(shù)是多少?
maxConcurrentDownloads = 6
4> SDWebImage 支持動圖嗎病袄?GIF
#import <ImageIO/ImageIO.h>
[UIImage animatedImageWithImages:images duration:duration];```
5> SDWebImage是如何區(qū)分不同格式的圖像的
根據(jù)圖像數(shù)據(jù)第一個字節(jié)來判斷的搂赋!
PNG:0x89
JPG:0xFF
GIF:0x47```
6> SDWebImage 緩存圖片的名稱是怎么確定的赘阀!
md5
如果單純使用 文件名保存,重名的幾率很高脑奠!
使用 MD5 的散列函數(shù)基公!對完整的 URL 進行 md5,結果是一個 32 個字符長度的字符串宋欺!```
7> SDWebImage 的內存警告是如何處理的轰豆!
利用通知中心觀察
- UIApplicationDidReceiveMemoryWarningNotification 接收到內存警告的通知
執(zhí)行 clearMemory 方法,清理內存緩存齿诞! - UIApplicationWillTerminateNotification 接收到應用程序將要終止通知
執(zhí)行 cleanDisk 方法酸休,清理磁盤緩存! - UIApplicationDidEnterBackgroundNotification 接收到應用程序進入后臺通知
執(zhí)行 backgroundCleanDisk 方法祷杈,后臺清理磁盤斑司!
通過以上通知監(jiān)聽,能夠保證緩存文件的大小始終在控制范圍之內但汞!
clearDisk 清空磁盤緩存宿刮,將所有緩存目錄中的文件,全部刪除私蕾! 實際工作僵缺,將緩存目錄直接刪除,再次創(chuàng)建一個同名空目錄踩叭!
###3.談談工作中有沒有二次封裝過第三方框架磕潮,都封裝過哪些,舉例說明容贝。
此類與工作經(jīng)驗密切相關揉抵。如AFN的二次封裝。
##3??. 說說NSTimer創(chuàng)建后嗤疯,會在哪個線程運行冤今。runloop和線程的關系?
有兩種創(chuàng)建NSTimer的方式
第一種:scheduled創(chuàng)建的定時器會自動以默認方式(NSDefaultRunLoopMode)加入到當前運行循環(huán)里面
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(setNumLabelNum) userInfo:nil repeats:YES];
第二種: timerWithTimeInterval創(chuàng)建的定時器需要手動加入到當前運行循環(huán)里
NSTimer *timer = [NSTimer timerWithTimeInterval:1 target:self selector:@selector(setNumLabelNum) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
kCFRunLoopDefaultMode:默認模式茂缚,不能再交互時保持運行
NSRunLoopCommonModes : 是模式組,包含多種模式,可以在交互的時候保持運行;kCFRunLoopDefaultMode 和 UITrackingRunLoopMode
RunLoop 和線程
RunLoop 的作用就是來管理線程的戏罢,當線程的 RunLoop
開啟后,線程就會在執(zhí)行完任務后脚囊,處于休眠狀態(tài)龟糕,隨時等待接受新的任務,而不是退出悔耘。
只有主線程的RunLoop是默認開啟的讲岁,所以程序在開啟后,會一直運行,不會退出缓艳。其他線程的RunLoop
如果需要開啟校摩,就手動開啟,
判斷下面運行循環(huán)能否執(zhí)行 阶淘。執(zhí)行幾次衙吩?
(void)viewDidLoad {
[super viewDidLoad];
_timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(runTimer) userInfo:nil repeats:YES];
[_timer fire];
}(void)runTimer{
[NSThread detachNewThreadSelector:@selector(startTimer) toTarget:self withObject:nil];
}(void)startTimer
{
NSLog(@"我運行幾次?");
}
猜想runloop內部是如何實現(xiàn)的溪窒?
1坤塞、有一個判斷循環(huán)的條件,滿足條件澈蚌,就一直循環(huán)
2摹芙、線程得到喚醒事件被喚醒,事件處理完畢以后宛瞄,回到睡眠狀態(tài)浮禾,等待下次喚醒。
##4??. objc中向一個nil對象發(fā)送消息將會發(fā)生什么坛悉?
在Objective-C中向nil發(fā)送消息是完全有效的——只是在運行時不會有任何作用。Cocoa中的幾種模式就利用到了這一點承绸。發(fā)向nil的消息的返回值也可以是有效的:
? 如果一個方法返回值是一個對象裸影,那么發(fā)送給nil的消息將返回0(nil)。例如:Person * motherInlaw = [ aPerson spouse] mother]; 如果spouse對象為nil军熏,那么發(fā)送給nil的消息mother也將返回nil轩猩。
? 如果方法返回值為指針類型,其指針大小為小于或者等于sizeof(void*)荡澎,float均践,double,long double 或者long long的整型標量摩幔,發(fā)送給nil的消息將返回0彤委。
? 如果方法返回值為結構體,正如在《Mac OS X ABI 函數(shù)調用指南》或衡,發(fā)送給nil的消息將返回0焦影。結構體中各個字段的值將都是0。其他的結構體數(shù)據(jù)類型將不是用0填充的封断。
? 如果方法的返回值不是上述提到的幾種情況斯辰,那么發(fā)送給nil的消息的返回值將是未定義的。
下面的代碼段就是一個有效地向nil發(fā)送消息的示例:
//id anObjectMybeNil = nil;
//這種寫法是有效的
if ( [ anObjectMaybeNil methordThatReturnADouble] == 0.0 )
{
//其他的實現(xiàn)代碼
}
注意:在Mac OS X v10.5版本中坡疼,向nil發(fā)送消息的結果與上面的描述會稍有不同彬呻。在Mac OS X v10.4以及更以前的版本中,向nil發(fā)送消息是完全有效的,只要消息的返回值是對象闸氮,任意類型的指針剪况,void,或者是其他大小小于或者等于sizeof(void*)的整型標量湖苞。此時拯欧,發(fā)送給nil的消息將返回nil。如果發(fā)送nil的消息的返回值不是上述幾種類型(比如說返回的類型是結構體财骨,或者是浮點類型镐作,或者是向量類型的),其返回值則是未定義的隆箩。因此该贾,在Mac OS X v10.4以及更老的版本中,我們不應該依賴于發(fā)送給nil對象的消息的返回值捌臊,除非該消息的返回值是一個對象杨蛋,任意類型的指針,或者是任意大小小于或者是等于sizeof(void *)的整型標量理澎。
##???. 比較一下objc中的類方法和實例方法逞力?
1、類方法是屬于整個類糠爬,而不屬于某個對象寇荧。
2、類方法只能訪問類成員變量执隧,不能訪問實例變量揩抡,而實例方法可以訪問類成員變量和實例變量。
3镀琉、類方法的調用可以通過類名.類方法和對象.類方法峦嗤,而實例方法只能通過對象.實例方法訪問。
4屋摔、類方法只能訪問類方法烁设,而實例方法可以訪問類方法和實例方法。
5钓试、類方法不能被覆蓋署尤,實例方法可以被覆蓋。
實例方法是— 類開頭是+ 實例方法是用實例對象訪問亚侠,類方法的對象是類而不是實例曹体,通常創(chuàng)建對象或者工具類。
在實例方法里硝烂,根據(jù)繼承原理發(fā)送消息給self和super其實都是發(fā)送給self
在類方法里面self是其他的類的類方法箕别,在類方法中給self發(fā)送消息只能發(fā)類方法self是類super也是
什么時候用類方法,要創(chuàng)建一個實例時候獲取一個共享實例,或者獲取關于類的一些共有信息
##6??. @property 相關
###1. @property 后面可以有哪些修飾符串稀?
線程安全的: atomic,nonatomic
訪問權限的:readonly,readwrite
內存管理(ARC):assign,strong,weak,copy
內存管理(MRC):assign,retain,copy
指定方法名稱 :setter,getter
###2. 什么情況使用 weak 關鍵字除抛,相比 assign 有什么不同?比如:
在MRC環(huán)境下使用retain修飾對象類型,使用assign實現(xiàn)基本類型;
在ARC環(huán)境下,strong相當于retain,weak相當于assign,不對對象的引用計數(shù)+1;
目前 assigin 可以既可以用于修飾非OC對象也可以修飾OC對象,而weak必須用于修飾OC對象母截。
![weak與assign對比](http://i4.buimg.com/567571/d0d193725f17d3df.jpg "Title")
`weak 和 assign 的主要區(qū)別`:也是為什么控件用weak不用assign修飾:
對象銷毀后到忽,weak 修飾的 property 會自動設置為 nil,這個最大的好處就是之后發(fā)送的消息都不會因為對象銷毀而出錯清寇;assign 修飾的 property 并不會自動變?yōu)?nil喘漏,形成野指針,所以在此之后如果沒有判斷對象是否銷毀的話华烟,很有可能就會對野指針發(fā)送消息導致crash翩迈。
官方來說,如果不想增加持有對象的引用計數(shù)器的話盔夜,推薦使用 weak 而不是 assign负饲,這一點從 Apple 提供的頭文件就可以看出——所有 delegate 的修飾符都是 weak。
weak 此特質表明該屬性定義了一種“非擁有關系” (nonowning relationship)喂链。為這種屬性設置新值時返十,設置方法既不保留新值,也不釋放舊值椭微。此特質同assign類似洞坑, 然而在屬性所指的對象遭到摧毀時,屬性值也會清空(nil out)赏表。 而 assign 的“設置方法”只會執(zhí)行針對“純量類型” (scalar type检诗,例如 CGFloat 或 NSlnteger 等)的簡單賦值操作匈仗。
在ARC中,出現(xiàn)循環(huán)引用的時候,必須要有一端使用weak,比如:自定義View的代理屬性,已經(jīng)自身已經(jīng)對它進行一次強應用,沒有必要在強引用一次,此時也會使用weak,自定義View的子控件屬性一般也使用weak;但是也可以使用strong
當父控件銷毀的時候,指向對象的指針會被自動設置為nil瓢剿,對象沒有強指針指向也會被銷毀。
strong - 定義OC對象悠轩,根視圖间狂,父視圖
weak - 代理,子控件火架,解決block循環(huán)引用時
copy - 字符串鉴象,block,可變的集合(NSMutableArray ,dictM,SetM)
###3. 為什么字符串不用strong 而用copy何鸡?
copy此特質所表達的所屬關系與strong類似纺弊。然而設置方法并不保留新值,而是將其“拷貝” (copy)骡男。 當屬性類型為NSString時淆游,經(jīng)常用此特質來保護其封裝性,因為傳遞給設置方法的新值有可能指向一個NSMutableString類的實例。這個類是NSString的子類犹菱,表示一種可修改其值的字符串拾稳,此時若是不拷貝字符串,那么設置完屬性之后腊脱,字符串的值就可能會在對象不知情的情況下遭人更改访得。所以,這時就要拷貝一份“不可變” (immutable)的字符串陕凹,確保對象中的字符串值不會無意間變動悍抑。只要實現(xiàn)屬性所用的對象是“可變的” (mutable),就應該在設置新屬性值時拷貝一份捆姜。
用@property聲明 NSString传趾、NSArray、NSDictionary 經(jīng)常使用copy關鍵字泥技,是因為他們有對應的可變類型:NSMutableString浆兰、NSMutableArray、NSMutableDictionary珊豹,他們之間可能進行賦值操作簸呈,為確保對象中的字符串值不會無意間變動,應該在設置新屬性值時拷貝一份店茶。
保證其恒定性蜕便。
###4、關于block變量為什么用copy贩幻?
block 使用 copy 是從 MRC 遺留下來的“傳統(tǒng)”,在 MRC 中,方法內部的 block 是在棧區(qū)的,使用 copy 可以把它放到堆區(qū).在 ARC 中寫不寫都行:對于 block 使用 copy 還是 strong 效果是一樣的轿腺,但寫上 copy 也無傷大雅,還能時刻提醒我們:編譯器自動對 block 進行了 copy 操作丛楚。如果不寫 copy 族壳,該類的調用者有可能會忘記或者根本不知道“編譯器會自動對 block 進行了 copy 操作”,他們有可能會在調用之前自行拷貝屬性值趣些。這種操作多余而低效仿荆。
~~只有copy后的Block才會在堆中~~ **不正確的**, 在ARC中引用外部變量的block系統(tǒng)默認到堆區(qū)坏平。不引用外部變量的block在棧區(qū)拢操。但是在實際開發(fā)中,不引用外部變量的block是不存在的舶替。棧中的Block的生命周期是和棧綁定的 令境。
在MRC下防止循環(huán)引用
__block typeof(self) weakSelf = self;
在ARC下防止循環(huán)引用
__weak typeof(self) weakSelf=self;
因為MRC下沒有__weak
##7??. KVC與KVO理解
KVC,即是指 NSKeyValueCoding顾瞪,一個非正式的 Protocol舔庶,提供一種機制來間接訪問對象的屬性返劲。KVO 就是基于 KVC 實現(xiàn)的關鍵技術之一。
一個對象擁有某些屬性栖茉。比如說篮绿,一個 Person 對象有一個 name 和一個 address 屬性。以 KVC 說法吕漂,Person 對象分別有一個 value 對應他的 name 和 address 的 key亲配。 key 只是一個字符串,它對應的值可以是任意類型的對象惶凝。從最基礎的層次上看吼虎,KVC 有兩個方法:一個是設置 key 的值,另一個是獲取 key 的值苍鲜。
Key-Value Observing (KVO) 建立在 KVC 之上思灰,它能夠觀察一個對象的 KVC key path 值的變化。
[KVC與KVO詳解](http://magicalboy.com/kvc_and_kvo/ "Title")
##8??. UIView 與CALayer的關系
說出自己的理解
UIView類似于畫布混滔,CALayer類似于畫筆
[CALayer與UIView的關系](http://www.cnblogs.com/yswdarren/p/3555436.html "Title")
CALayer屬于Core Animation
1. UIView是iOS系統(tǒng)中界面元素的基礎洒疚,所有的界面元素都是繼承自它。它本身完全是由CoreAnimation來實現(xiàn)的坯屿。它真正的繪圖部分油湖,是由一個CALayer類來管理。UIView本身更像是一個CALayer的管理器领跛,訪問它的跟繪圖和跟坐標有關的屬性乏德,例如frame,bounds等吠昭,實際上內部都是在訪問它所包含的CALayer的相關屬性喊括。
2. UIView 有一個屬性layer∈概铮可以返回它的CALayer實例郑什。所有從UIView繼承來的對象都繼承了這個屬性。這意味著你可以轉換幻妓、縮放蹦误、旋轉劫拢,甚至可以在Navigation bars肉津,Tables,Text boxes等其它的View類上增加動畫舱沧。每個UIView都有一個層妹沙,控制著各自的內容最終被顯示在屏幕上的方式。
3. CALayer的坐標系統(tǒng)比UIView多了一個anchorPoint屬性熟吏,使用CGPoint結構表示距糖,值域是0~1玄窝。
##9??數(shù)據(jù)持久化存儲方案有哪些?
plist文件(屬性列表)
preference(偏好設置)
NSKeyedArchiver(歸檔)
SQLite 3
CoreData
[數(shù)據(jù)持久化存儲方案](http://www.cocoachina.com/ios/20150720/12610.html "Title")
##1??0??多線程實現(xiàn)方式
4種實現(xiàn)方式 常用3種
Pthreads
NSThread
GCD
NSOperation & NSOperationQueue
[關于iOS多線程悍引,你看我就夠了](http://www.reibang.com/p/0b0d9b1f1f19 "Title")
##1??1??網(wǎng)絡請求的GET 和POST的區(qū)別
一般情況下恩脂,Get是向服務器發(fā)索取數(shù)據(jù)的一種請求,而Post是向服務器提交數(shù)據(jù)的一種請求趣斤。
1. GET請求的數(shù)據(jù)會附在URL之后(就是把數(shù)據(jù)放置在HTTP協(xié)議頭中)俩块,以?分割URL和傳輸數(shù)據(jù),參數(shù)之間以&相連浓领,如:login.action?name=hyddd&password=idontknow&verify=%E4%BD%A0%E5%A5%BD玉凯。如果數(shù)據(jù)是英文字母/數(shù)字,原樣發(fā)送联贩,如果是空格漫仆,轉換為+,如果是中文/其他字符泪幌,則直接把字符串用BASE64加密盲厌,得出如:%E4%BD%A0%E5%A5%BD,其中%XX中的XX為該符號以16進制表示的ASCII祸泪。
2. POST把提交的數(shù)據(jù)則放置在是HTTP包的包體(請求頭狸眼、請求體)中。POST的安全性要比GET的安全性高浴滴。注意:這里所說的安全性和上面GET提到的“安全”不是同個概念拓萌。上面“安全”的含義僅僅是不作數(shù)據(jù)修改,而這里安全的含義是真正的Security的含義升略,比如:通過GET提交數(shù)據(jù)微王,用戶名和密碼將明文出現(xiàn)在URL上,因為(1)登錄頁面有可能被瀏覽器緩存品嚣,(2)其他人查看瀏覽器的歷史紀錄炕倘,那么別人就可以拿到你的賬號和密碼了。
>我們更應關注的是每道題背后所包含的理論知識體系翰撑。謹記面試題只是武功招式罩旋,知識體系才是內功心法。