總結一下常見的面試題,一般初級iOS Developer記住的都是招式假夺,但招式何其多淮蜈,面試的時候總會有遺漏和盲區(qū),內功心法才是一通萬通已卷,能以不變應萬變。這份面試題你答不全不能說明你iOS不及格淳蔼,你全答對了你也不能上天侧蘸。真正應該關注的是這份題背后所包含的理論知識體系。
內存管理
多線程實現方式
動畫技術
繪圖技術
設計模式
Objective-C的一些語言特性
「 說說你對ARC和MRC的認識鹉梨? 」
ARC:Automatic Reference Counting 自動引用計數
MRC:Mannul Reference Counting 手動引用計數
ARC是基于MRC的讳癌,本質都是管理對象的retainCount屬性,不同的是管理內存代碼是由誰來寫存皂。
MRC要求程序員自己寫代碼管理對象的retainCount屬性晌坤,
而在ARC下,編譯器編譯代碼的時候旦袋,會自動根據當前代碼的情況添加對象的內存管理的代碼骤菠。
之所以要管理內存,是因為對象在堆中疤孕,不會自動回收商乎。如果不去管理,那就要等到程序結束才回收祭阀。如果用戶一直在使用鹉戚,會導致內存的占用越來越大鲜戒。
說到這里,必須說一下內存管理的原則抹凳。
1>對象創(chuàng)建后遏餐,要對應一次release
2>哪個指針retain了對象,就用哪個指針release對象
3>retain的次數要和release相匹配
4>在對象被釋放前赢底,指針不可設為nil或指向別的對象境输,因為會出現內存泄漏
MRC下要注意的問題:對象之間的循環(huán)retain
ARC下要注意的總是:對象之間的循環(huán)引用
Xcode 4.1之后 才有ARC
ARC下,不顯示指定任何屬性關鍵字時颖系,默認的關鍵字都有哪些嗅剖?
對應基本數據類型默認關鍵字是
atomic,readwrite,assign
對于普通的OC對象
atomic,readwrite,strong
「 談談工作中你是如何做圖片緩存的? 」
一般用第三方框架SDWebImage
SDWebImage庫的作用:
通過對UIImageView的類別擴展來實現異步加載替換圖片的工作。
主要用到的對象:
1.UIImageView (WebCache)類別嘁扼,入口封裝信粮,實現讀取圖片完成后的回調。
2.SDWebImageManager趁啸,對圖片進行管理的中轉站强缘,記錄那些圖片正在讀取。向下層讀取Cache(調用SDImageCache)不傅,或者向網絡讀取對象( 調用SDWebImageDownloader )旅掂。實現SDImageCache和SDWebImageDownloader的回調。
3.SDImageCache访娶,根據據URL的MD5摘要對圖片進行存儲和讀壬膛啊(實現存在內存中或者存在硬盤上兩種實現)實現圖片和內存清理工作。
4.SDWebImageDownloader崖疤,根據URL向網絡讀取數據(實現部分讀取和全部讀取后再通知回調兩種方式)
5.SDWebImageDecoder秘车,異步對圖像進行了一次解壓.由于UIImage的imageWithData函數是每次畫圖的時候才將Data解壓成ARGB的圖像,所以在每次畫圖的時候劫哼,會有一個解壓操作叮趴,這樣效率很低,但是只有瞬時的內存需求权烧。為了提高效率通過SDWebImageDecoder將包裝在Data下的資源解壓眯亦,然后畫在另外一張圖片上,這樣這張新圖片就不再需要重復解壓了般码。
1妻率、SDImageCache是怎么做數據管理的?SDImageCache分兩個部分,一個是內存層面的侈询,一個是硬盤層面的舌涨。內存層面的相當是個緩存器,以Key-Value的形式存儲圖片。當內存不夠的時候會清除所有緩存圖片囊嘉。用搜索文件系統的方式做管理温技,文件替換方式是以時間為單位,剔除時間大于一周
的圖片文件扭粱。當SDWebImageManager向SDImageCache要資源時舵鳞,先搜索內存層面的數據,如果有直接返回琢蛤,沒有的話去訪問磁盤蜓堕,將圖片從磁盤讀取出來,然后做Decoder博其,將圖片對象放到內存層面做備份套才,再返回調用層。
SDWebImage原理及使用
「 說說NSTimer創(chuàng)建后慕淡,會在哪個線程運行背伴。runloop和線程的關系? 」
// 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 如果需要開啟侦啸,就手動開啟丛肮,
//猜想runloop內部是如何實現的寥假?
1佳遂、有一個判斷循環(huán)的條件他嫡,滿足條件械蹋,就一直循環(huán)
2降传、線程得到喚醒事件被喚醒至非,事件處理完畢以后钠署,回到睡眠狀態(tài),等待下次喚醒荒椭。
「 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 函數調用指南》,發(fā)送給nil的消息將返回0星持。
結構體中各個字段的值將都是0抢埋。其他的結構體數據類型將不是用0填充的。
? 如果方法的返回值不是上述提到的幾種情況钉汗,那么發(fā)送給nil的消息的返回值將是未定義的羹令。
下面的代碼段就是一個有效地向nil發(fā)送消息的示例:
//id anObjectMybeNil = nil;
//這種寫法是有效的
if ( [ anObjectMaybeNil methordThatReturnADouble] == 0.0 ) { //其他的實現代碼 }
注意:在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)建對象或者工具類羽戒。
在實例方法里,根據繼承原理發(fā)送消息給self和super其實都是發(fā)送給self
在類方法里面self是其他的類的類方法虎韵,在類方法中給self發(fā)送消息只能發(fā)類方法self是類super也是
什么時候用類方法易稠,要創(chuàng)建一個實例時候獲取一個共享實例,或者獲取關于類的一些共有信息
「 @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實現基本類型;
在ARC環(huán)境下,strong相當于retain,weak相當于assign,不對對象的引用計數+1;
assigin 可以用非OC對象,而weak必須用于OC對象测萎。
在ARC中,出現循環(huán)引用的時候,必須要有一端使用weak,比如:自定義View的代理屬性,已經自身已經對它進行一次強應用,沒有必要在強引用一次,此時也會使用weak,自定義View的子控件屬性一般也使用weak;但是也可以使用strong
當父控件銷毀的時候,指向對象的指針會被自動設置為nil亡电,對象沒有強指針指向也會被銷毀。
3.為什么字符串不用strong 而用copy硅瞧?
copy此特質所表達的所屬關系與strong類似份乒。然而設置方法并不保留新值,而是將其“拷貝” (copy)腕唧。
當屬性類型為NSString時冒嫡,經常用此特質來保護其封裝性,因為傳遞給設置方法的新值有可能指向一個NSMutableString類的實例四苇。
這個類是NSString的子類,表示一種可修改其值的字符串方咆,此時若是不拷貝字符串月腋,那么設置完屬性之后,
字符串的值就可能會在對象不知情的情況下遭人更改。
所以榆骚,這時就要拷貝一份“不可變” (immutable)的字符串片拍,確保對象中的字符串值不會無意間變動。
只要實現屬性所用的對象是“可變的” (mutable)妓肢,就應該在設置新屬性值時拷貝一份捌省。
用@property聲明 NSString、NSArray碉钠、NSDictionary 經常使用copy關鍵字纲缓,是因為他們有對應的可變類型:NSMutableString、NSMutableArray喊废、NSMutableDictionary祝高,他們之間可能進行賦值操作,為確保對象中的字符串值不會無意間變動污筷,應該在設置新屬性值時拷貝一份工闺。保證其恒定性。
「 KVC與KVO理解 」
KVC瓣蛀,即是指 NSKeyValueCoding陆蟆,一個非正式的 Protocol,提供一種機制來
間接訪問對象的屬性惋增。KVO 就是基于 KVC 實現的關鍵技術之一叠殷。
一個對象擁有某些屬性。比如說器腋,一個 Person 對象有一個 name 和一個 address 屬性溪猿。以 KVC 說法,Person 對象分別有一個 value 對應他的 name 和 address 的 key纫塌。 key 只是一個字符串诊县,它對應的值可以是任意類型的對象。從最基礎的層次上看措左,KVC 有兩個方法:一個是設置 key 的值依痊,另一個是獲取 key 的值。
Key-Value Observing (KVO) 建立在 KVC 之上怎披,它能夠觀察一個對象的 KVC key path 值的變化胸嘁。
「 UIView 與CALayer的關系 」
說出自己的理解
UIView類似于畫布,CALayer類似于畫筆
CALayer與UIView的關系
CALayer屬于Core Animation
1.UIView是iOS系統中界面元素的基礎凉逛,所有的界面元素都是繼承自它性宏。它本身完全是由CoreAnimation來實現的。
它真正的繪圖部分状飞,是由一個CALayer類來管理毫胜。UIView本身更像是一個CALayer的管理器书斜,訪問它的跟繪圖和
跟坐標有關的屬性,例如frame酵使,bounds等荐吉,實際上內部都是在訪問它所包含的CALayer的相關屬性。
2.UIView 有一個屬性layer口渔⊙溃可以返回它的CALayer實例。所有從UIView繼承來的對象都繼承了這個屬性缺脉。
這意味著你可以轉換痪欲、縮放、旋轉枪向,甚至可以在Navigation bars勤揩,Tables,Text boxes等其它的View類上
增加動畫秘蛔。每個UIView都有一個層陨亡,控制著各自的內容最終被顯示在屏幕上的方式。
3.CALayer的坐標系統比UIView多了一個anchorPoint屬性深员,使用CGPoint結構表示负蠕,值域是0~1。
「 數據持久化存儲方案有哪些倦畅? 」
plist文件(屬性列表)
preference(偏好設置)
NSKeyedArchiver(歸檔)
SQLite 3CoreData
「 多線程實現方式 」
4種實現方式 常用3種
Pthreads
NSThread
GCD
NSOperation & NSOperationQueue
「 網絡請求的GET 和POST的區(qū)別 」
一般情況下,Get是向服務器發(fā)索取數據的一種請求叠赐,而Post是向服務器提交數據的一種請求欲账。
1.GET請求的數據會附在URL之后(就是把數據放置在HTTP協議頭中),以?分割URL和傳輸數據芭概,參數之間以&相連赛不,
如:login.action?name=hyddd&password=idontknow&verify=%E4%BD%A0%E5%A5%BD。如果數據是英文字母/數字罢洲,
原樣發(fā)送踢故,如果是空格,轉換為+惹苗,如果是中文/其他字符殿较,則直接把字符串用BASE64加密,得出如:%E4%BD%A0%E5%A5%BD桩蓉,
其中%XX中的XX為該符號以16進制表示的ASCII淋纲。
2.POST把提交的數據則放置在是HTTP包的包體(請求頭、請求體)中院究。POST的安全性要比GET的安全性高帚戳。
注意:這里所說的安全性和上面GET提到的“安全”不是同個概念玷或。上面“安全”的含義僅僅是不作數據修改,而這里安全的含義是真正的
Security的含義片任,比如:通過GET提交數據,用戶名和密碼將明文出現在URL上蔬胯,因為(1)登錄頁面有可能被瀏覽器緩存对供,
(2)其他人查看瀏覽器的歷史紀錄,那么別人就可以拿到你的賬號和密碼了氛濒。