iOS面試題整理

最近在找工作,整理了幾個比較基礎(chǔ)的面試題,回答僅供回顧,不是太深入,也不一定正確,平時還是應(yīng)該有目的性的深入理解。

1.深拷貝與淺拷貝
回答:
深拷貝是新拷貝一塊內(nèi)存交給對象使用,copy聲明的就是深拷貝。
淺拷貝是創(chuàng)建一個新對象,兩個對象指向同一個內(nèi)存地址,ratain聲明的就是淺拷貝。
在oc中只有一種情況下是淺拷貝,就是不可變對象的copy,其它的都是深拷貝(包括不可變對象的mutableCopy、可變對象的copy和mutableCopy)。

2.retain、strong、assign、weak、copy、nonatomic和atomic分別是做什么的
回答:
atomic是聲明屬性為原子屬性,線程安全的,為防止屬性在寫的過程中被另一個線程讀取,造成數(shù)據(jù)錯誤,一般用于讀取文件,在手機端很少使用(桌面端會使用),應(yīng)避免使用,因為它底層的實現(xiàn)是自旋鎖(對應(yīng)的為同步鎖,也叫互斥鎖,這是線程同步的知識)性能比較低,最好找其他的方式代替,比如通過改變代碼邏輯的方式,屬性默認(rèn)是atomic。
nonatomic是聲明屬性為非原子屬性,是線程不安全的。
assign是默認(rèn)的值,用以聲明基礎(chǔ)數(shù)據(jù)類型(NSInteger、CGFloat)和C數(shù)據(jù)類型(int、float)。
retain用于聲明對象。
copy只對實行了NSCopying協(xié)議的對象類型有效,也是用于聲明對象。
strong用來聲明一個強引用的屬性,對應(yīng)retain和copy。
weak聲明一個弱引用的屬性,可以自動nil化。
unsafe_unretained也是聲明一個弱引用屬性,但不會自動nil化,也就是說,如果內(nèi)存被釋放掉,這個指針就是一個野指針。

3.objective-c的內(nèi)存管理原理
oc為每塊內(nèi)存設(shè)定一個引用計數(shù),當(dāng)內(nèi)存被賦值給a對象時,引用計數(shù)加1,當(dāng)內(nèi)存又被賦值給b對象時,引用計數(shù)再加1,這時候引用計數(shù)是2,當(dāng)a不再使用這塊內(nèi)存時,引用計數(shù)減1,當(dāng)b不再使用這塊內(nèi)存時,本來引用計數(shù)應(yīng)該再減1,變成0,但是這時候系統(tǒng)為了減少系統(tǒng)開支,不會進行減1操作,而會直接將內(nèi)存釋放掉。

4.UIView、UIWindow和CALayer的聯(lián)系和區(qū)別
回答:
UIView負(fù)責(zé)渲染矩形區(qū)域的內(nèi)容,為矩形區(qū)域增加動畫和相應(yīng)的觸摸事件,布局和管理多個子視圖。
UIWindow是一個特殊的UIView,而一個程序中通常只有一個UIWindow,但可以手動創(chuàng)建多個。
UIWindow主要起到三個作用:
1.作為容器,包含程序所有要顯示的視圖;
2.傳遞觸摸消息到其它的UIView或者其它對象;
3.與UIViewController協(xié)同工作,完成設(shè)備方向旋轉(zhuǎn)的支持。
CALayer是繪制內(nèi)容的,不處理事件響應(yīng),與UIView是相互依賴的,依賴于UIView來顯示繪制內(nèi)容,UIView依賴于CALayer來提供內(nèi)容。

  1. @implementation Son : Father
    • (id)init {
      if (self = [super init]) {
      NSLog(@"%@“, NSStringFromClass([self class]));
      NSLog(@"%@“, NSStringFromClass([super class]));
      NSLog(@"%@“, NSStringFromClass(self.superclass));
      }
      return self;
      }
      @end
      //打印結(jié)果就是
      Son
      Son
      Father
      為什么呢?
      回答:
      因為self和super的消息主體依然是self,也就是說self和super指向的是同一個對象,只是查找方法的位置有區(qū)別,一個從本類,一個從本類的超類。
      一般情況下class方法只在根類NSObject中定義,極少情況有子類重寫class方法,所以[self calss]和[super class]都是在根類中找方法實現(xiàn),如果重寫可能會不太一樣。

6.#import、#include和@class的聯(lián)系和區(qū)別
回答:
通常引用一個類有兩種方法,一種是#import,另一種是@class,兩者的區(qū)別在于#import會包含引用類的所有信息,包括被引用類的屬性和方法,而@class只會告訴編譯器聲明了一個類,而類中有什么信息不需要知道。

import被確定每個文件只會被引用一次,而#include會被多次引用,容易引起交叉編譯。

7.手寫block與反寫block
回答:

typedef void(^selectRowAtIndex)(NSInteger index);
@property (nonatomic, copy) selectRowAtIndex handle;

[UIView transitionWithView:self.view
                             duration:0.2
                              options:UIViewAnimationOptionTransitionFlipFromLeft
                         animations:^{ 
                                       [[blueViewController view] removeFromSuperview];
                                       [[self view] insertSubview:yellowViewController.view atIndex:0];
                                      }
                         completion:nil];
typedef void(^animations)(void);
typedef void(^completion)(BOOL finished);

8.類別(category)和繼承的區(qū)別
回答:
類別是對一個功能完備類的補充,比如一個Animal類,具有run和eat方法,想給類增加一個bark方法,可以使用類別。
而多個類具有相同的實例變量和方法時,考慮用繼承,即子類可以繼承父類相同的特性,比如Animal類具有年齡和體重兩個屬性,Dog也具有年齡和體重兩個屬性,Dog就可以繼承Animal的兩個屬性,即為繼承。
共同點是都給類進行了擴展。
區(qū)別是:
1.類別是對方法的擴展,不能添加成員變量,繼承可以在父類的成員變量基礎(chǔ)上添加新的成員變量。
2.類別只能添加新方法,而不能修改和刪除原來的方法,繼承可以增加、修改和刪除方法。
3.類別不提倡對原有方法進行重載,繼承可以使用super對原來的方法進行重載。
4.類別可以被繼承,如果一個父類中定義了一個類別,那么子類中也會繼承此類別。

9.__block與__weak的區(qū)別
回答:
__block對象在block中是可以被修改和重新賦值的。
__block可以修飾對象和基本數(shù)據(jù)類型,而__weak只能修飾對象。
__weak對象不可以在block中被重新賦值。

10.多線程
回答:
多線程的實現(xiàn)方式包括:
Pthreads 跨平臺,使用難度大,很少使用。
NSThread 更加面向?qū)ο?,可直接操作線程對象。生命周期需要自己手動管理,最常用的可能是暫停功能- (void)sleepForTimeInterval:(NSTimeInterval)time;
GCD 基于C語言,取代NSThread,充分利用設(shè)備多核,常用,會自動管理線程的生命周期。
GCD是基于任務(wù)和隊列來進行的,隊列遵循FIFO(先進先出)原則,隊列氛圍并行隊列和串行隊列。
NSOperation & NSOperationQueue 對GCD的封裝,比GCD更加面向?qū)ο?,比GCD性能稍微差一點,常用。
NSOperation與NSOperationQueue分別對應(yīng)GCD中的任務(wù)和隊列的概念。

11.isKindOfClass和isMemberOfClass的區(qū)別
回答:
isKindOfClass可以確定一個對象是否是一個類的實例,或者該類祖先類的實例,而isMemberOfClass只能用來判斷前者,不能用來判斷后者。

12.UCP和TCP的區(qū)別
回答:
TCP(傳輸控制協(xié)議),提供的是面向連接、可靠的字節(jié)流服務(wù)。當(dāng)客戶和服務(wù)器彼此交換數(shù)據(jù)前,必須先在雙方之間建立一個TCP連接,之后才能傳輸數(shù)據(jù)。TCP提供超時重發(fā),丟棄重復(fù)數(shù)據(jù),流量控制等功能,保證能從一端傳到另一端。
UDP(用戶數(shù)據(jù)協(xié)議),是一個簡單的面向數(shù)據(jù)的運輸層協(xié)議。UDP不提供可靠性,它只是把應(yīng)用程序傳給IP層的數(shù)據(jù)報發(fā)送出去,但是并不能保證它們能到達目的地。因為UDP在傳輸數(shù)據(jù)使不用在客戶和服務(wù)器之間建立一個連接,且沒有超時重發(fā)機制,所以傳輸速度很快。

13.delegate、block和NSNotification的區(qū)別
回答:
NSNotification發(fā)出消息后,可以有多個消息接受者,delegate效率比較高,delegate發(fā)出消息后只能由某個特定的對象獲得消息。
block可以代替delegate的功能,而且實現(xiàn)起來比較簡潔,delegate需要對每個事件進行判斷識別來源,而block可以在創(chuàng)建事件時區(qū)分開來。

14.KVO和KVC的區(qū)別
回答:
KVC即是指 NSKeyValueCoding,一個非正式的Protocol,提供一種機制來間接訪問對象的屬性。而不是通過調(diào)用Setter、Getter方法訪問。KVO 就是基于 KVC 實現(xiàn)的關(guān)鍵技術(shù)之一。
- (id)valueForKey:(NSString *)key;
- (void)setValue:(id)value forKey:(NSString *)key;
KVO的是KeyValue Observe的縮寫,中文是鍵值觀察。這是一個典型的觀察者模式,觀察者在鍵值改變時會得到通知。

addObserver:forKeyPath:options:context:;
observeValueForKeyPath:ofObject:change:context:

KVO需要注意在對象銷毀時,要移除觀察者,不然會崩潰。

removeObserver:forKeyPath:context:

KVO是同步執(zhí)行,不能執(zhí)行耗時方法,KVO可能發(fā)生資源搶奪

15.GCD
回答:

dispatch_get_global_queue 后臺執(zhí)行
dispatch_get_main_queue 主線程執(zhí)行
dispatch_once_t 一次性執(zhí)行
dispatch_time_t 延遲執(zhí)行
dispatch_group_async 并行執(zhí)行
dispatch_group_notify 并行執(zhí)行后匯總

還有自定義隊列

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • OC的理解與特性O(shè)C作為一門面向?qū)ο蟮恼Z言,自然具有面向?qū)ο蟮恼Z言特性:封裝、繼承、多態(tài)。它既具有靜態(tài)語言的特性(...
    LIANMING_LI閱讀 580評論 0 0
  • 基礎(chǔ) 1.為什么說Objective-C是一門動態(tài)的語言? 所謂的動態(tài)類型語言,意思就是類型的檢查是在運行時做的。...
    陽明AI閱讀 1,131評論 0 17
  • 面試題摘錄于網(wǎng)絡(luò), 用于個人復(fù)習(xí)使用。 id 聲明的對象有什么特性? 答:id 聲明的對象具有運行時的特性,即可以...
    普通青年閱讀 481評論 0 0
  • *面試心聲:其實這些題本人都沒怎么背,但是在上海 兩周半 面了大約10家 收到差不多3個offer,總結(jié)起來就是把...
    Dove_iOS閱讀 27,593評論 30 472
  • 《工作投入的心理奧秘》一書對工作投入進行了心理上的分析。個人覺得寫的挺不錯,于是進行了總結(jié)。 一、什么是工作投入?...
    BrianZhang閱讀 1,742評論 0 4

友情鏈接更多精彩內(nèi)容