iOS面試知識點梳理

1.iOS開發者帳號類型

  • 「我的」開發者能夠申請升級「公司」,能夠經過撥打蘋果公司客服電話(400 6701 855)來諮詢和辦理。
  • 公司帳號容許多個開發者進行協做開發,比我的多一些賬號管理的設置,可設置多個Apple ID,分4種管理級別的權限。申請公司帳號須要填寫公司的鄧白氏編碼(DUNS Number)。
  • 須要注意的是,企業帳號開發的應用不能上線App Store,適合那些不但願公開發布應用的企業。一樣,申請時也須要公司的鄧白氏編碼(DUNS Number)。

2.Property屬性

1.原子性:nonatomic 、atomic
2.讀寫: readwrite 、readonly
3.方法名:getter=<name>、setter=<name>
4.內存:strong、retain、copy、weak、assign 、unsafe_unretainedgit

atomic:原子性,只有一個線程能夠同時訪問實例。atomic 是線程安全的,至少在當前的讀取器是安全的。雖然它是一個默認屬性,可是因爲其使用同步鎖開銷較大,會損耗性能。
nonatomic:非原子性的,能夠被多個線程訪問。效率要比atomic 高,可是不能保證其在多線程狀態下的安全性,在單線程和明確只有一個線程訪問的狀況下被普遍使用。程序員

readwrite(默認值):表示其同時擁有getter 和 setter 方法;
readonly:只讀操做,其只有getter 方法,沒有setter法
注:若是某個實例只容許被外部讀取,而不能寫入操做,同時在類實現文件當中能夠寫入的話,能夠在頭文件中聲明屬性爲只讀的,在實現文件中設置其爲可讀寫的屬性,寫法以下:github

//頭文件中聲明爲: @property(nonatomic,readonly,copy) NSString *stringA; //實現文件中聲明爲: @property(nonatomic,readwrite,copy) NSString *stringA;

getter=<name>的樣式:
@property (nonatomic, getter=isOn) BOOL on;編程

 

assign:用於值類型(如int,float等)
weak: 用於修飾引用類型
unsafe_unretained:只修飾引用類型
區別:數組

  1. 三者修飾效果相同,即都不會更改所賦新值的引用計數,也不改變舊值的引用計數
  2. assign通常只修飾值類型,雖然也能夠修飾引用類型,可是修飾的對象釋放後,指針不會自動被置空,此時向對象發消息會崩潰。
  3. weak 不會產生野指針問題。由於weak修飾的對象釋放後(引用計數器值爲0),指針會自動被置nil,以後再向該對象發消息也不會崩潰。 weak是安全的。
  4. unsafe_unretained與assign的區別在於,其只修飾引用類型。

strong:用於引用類型,強引用。
retain :用於引用類型,強引用。
copy:修飾屬性會在內存裏拷貝對象。
區別:瀏覽器

  1. 三者都用於修飾引用類型。
  2. strong用於ARC,retain用於MRC。
  3. copy分爲淺層複製和深複製兩種,NSString、NSArray、NSDictionary等不可變類型都爲淺層複製,即其引用計數會+1,而不會建立新的內存。

 

3.瞭解沙盒的目錄結構

iOS應用沙盒即文件系統目錄,與其餘應用的文件系統隔離緩存

 

 

  • Documents:保存應用運行時生成的須要持久化的數據,如遊戲進度、塗鴉軟件的繪圖等信息, 該目錄會被iTunes同步備份。安全

  • Library/Caches:保存應用運行時生成的須要持久化的數據,iTunes同步設備時不會備份該目錄。通常存儲體積大、不須要備份的非重要數據,如緩存圖片或者離線數據(地圖等)。服務器

  • Library/Preference:保存應用的全部偏好設置,iOS的Settings(設置)應用會在該目錄中查找應用的設置信息。iTunes同步設備時會備份該目錄。多線程

  • tmp:保存應用運行時所需的臨時數據,使用完畢後再將相應的文件從該目錄刪除。應用沒有運行時,系統也可能會清除該目錄下的文件。iTunes同步設備時不會備份該目錄。從新手機、系統磁盤不足時都會被清理

4.理解內存中的區域劃分

棧區(stack):由系統自動分配和釋放,存放局部變量的值,容量小速度快,有序
:通常由程序員分配和釋放,若是不釋放,則出現內存泄露。程序會回收您的內存,特色:容量大,速度慢,無序
靜態存儲區:全局變量(外部變量)和靜態變量都存放在靜態區域。當程序結束使,系統回收
常量區:存放常量的內存區域,程序結束時,系統回收
代碼區:存放二進制代碼的區域

5.理解iOS的遠程推送

簡易推送流程:


(1) 應用程序安裝後提示用戶是否須要接收推送,用戶確認後註冊消息推送。
(2)App接收到從APNS Server獲取的令牌信息;
(3)APP將令牌信息發送到本身的服務器端;
(4)當須要向用戶推送消息時,本身的服務器將向蘋果的推送通知服務器(Apple Push Notification Service,如下簡稱 APNS)發送通知;
(5)APNS 會向裝有此APP的iPhone設備發送消息

第三方推送的原理(以個推爲例):

6.理解Block的使用

  1. Block爲何要用copy
    a、block在建立的時候默認分配的內存是在棧上,而不是在堆上。這樣的話其自己的做用域是屬於建立時候
    的做用域,一旦在建立的做用域以外調用就會致使程序的崩潰。因此使用了copy將其拷貝到堆內存上。
    b、block建立在棧上,而block的代碼中可能會用到本地的一些變量,只有將其拷貝到堆上,才能用這些變量

  2. Block爲何不用retain
    retain這是增長了一次計數,block的內存仍是在棧上,並無存在堆上,存在棧上的block可能隨時被系統回收。

  3. 爲何進入block中的對象引用計數須要自動加1
    Block執行的是回調,所以block並不知道其中的對象obj建立後會在何時被釋放,爲了避免在block使用obj以前,對象已經被釋放,block就retain了obj一次

  4. block和函數的關係
    Block的使用很像函數指針,不過與函數最大的不一樣是Block能夠訪問函數之外、詞法做用域之內的外部變量的值。
    換句話說,Block不只 實現函數的功能,還能攜帶函數的執行環境。

  5. 對於block的理解
    block其實是: 指向結構體的指針
    編譯器會將block的內部代碼生成對應的函數

  6. 對於基本數據類型,進入到block中會被當作常量處理

  //若是須要在block中對num進行修改,須要加上關鍵字__block
  //(咱們也能夠用static關鍵字進行修飾)
  int num1 = 10;
  void(^block1)() = ^{ NSLog(@"num1 is %d",num1); };
  num1 = 20; block1(); //輸出10
 
 
  //改進:使用block,使進入到block塊中的變量不被當作常量來使用
  __blockint num2 = 10;
  void(^block2)() = ^{ NSLog(@"num2 is %d",num2);
  };
  num2 = 20; block2(); //輸出20
 
  7.Block中self的循環引用
  block默認建立在棧上,因此對要對其進行執行copy操做,將其拷貝到堆區,便於更好的操做對象。可是執行了copy操做以後,block中使用self,此對象會被retain一次(注意:block在堆區上時纔會起到retain做用),會形成循環引用。
  解決方法:
  在MRC下,使用__block修飾
  在ARC下,使用__unsafe_unretained\weak修飾
 

7.理解循環引用出現的三種狀況:

  1. NSTimer
    NSTimer對象timer做爲一個對象A的屬性,本意在A的dealloc中釋放timer,可是timer沒有中止就不會觸發dealloc,而後就互相等待,形成循環引用。解決方法是顯式的調用timer的關閉方法[timer invaluate],再釋放A對象

  2. Block
    block代碼塊沒有配合weak使用

  3. Delegate
    聲明delegate時請用assign(MRC)或者weak(ARC)。

  循環引用舉例:

NSMutableArray *firstArray = [NSMutableArray array]; NSMutableArray *secondArray = [NSMutableArray array]; [firstArray addObject:secondArray]; [secondArray addObject:firstArray]; 

檢測循環引用
Xcode -> Product -> Pofile -> Leaks

8.理解指針的使用

用變量a給出下面的定義原文連接
a) 一個整型數
b) 一個指向整型數的指針
c) 一個指向指針的的指針,它指向的指針是指向一個整型數
d) 一個有10個整型數的數組
e) 一個有10個指針的數組,該指針是指向一個整型數的
f) 一個指向有10個整型數數組的指針
g) 一個指向函數的指針,該函數有一個整型參數並返回一個整型數
h) 一個有10個指針的數組,該指針指向一個函數,該函數有一個整型參數並返回一個整型數

a) int a; // An integer

b) int *a; // A pointer to an integer

c) int **a; // A pointer to a pointer to an integer

d) int a[10]; // An array of 10 integers

e) int *a[10]; // An array of 10 pointers to integers

f) int (*a)[10]; // A pointer to an array of 10 integers

g) int (*a)(int); // A pointer to a function a that takes an integer argument and returns an integer

h) int (*a[10])(int); // An array of 10 pointers to functions that take an integer argument and return an integer

九、理解iOS中的多線程

1.概念理解:
多線程是針對於單核的CPU來設計的,目的是爲了讓CPU快速在多個線程之間進行調度。
多線程的優缺點
優勢:提升程序的執行效率
缺點:開啓線程須要必定的內存空間

同步和異步:決定了可不能夠開啓新的線程
同步:在當前線程中執行任務,不具有開啓新線程的能力
異步:在新的線程中執行任務,具有開啓新線程的能力

並行與串行:決定了任務的執行方式
並行:多個任務併發(同時)執行。類型迅雷,多個任務同時開啓下載
串行:一個任務執行完畢後,再執行下一個任務。相似瀏覽器的一個接一個下載

 

iOS應用程序中都是一個主線程,也成爲UI線程
那麼主線程的做用就是用來更新UI,顯示或者刷新界面
注意:不能將耗時的任務放在主線程上,不然會出現卡頓的現象。

 

2.iOS的三種多線程編程技術
NSThread
直接操做線程對象,但須要手動管理生命週期,並且常用這種方式來查看當前線程
GCD(Grand Central Dispatch)
底層使用的是C語言,靈活方便,能夠根據系統負荷來增減線程,性能效率更好
Cocoa NSOperation
NSOperation對GCD的封裝,使用起來更好理解,將任務封裝爲NSOpertaion,添加到NSOPerationQueue對象中
子類化NSOpertaion的設計,更具備面向對象(封裝,複用)的特性。更加適合在複雜項目中使用

3.進程與線程
Progress和Thread,進程和線程是操做系統裏的基本概念
線程與進程的區別:
線程是資源分配的最小單位,也是處理器調度的基本單位,可是進程不是
進程是資源擁有的單位,同一個進程內的線程共享進程裏的資源
多進程,容許多個任務同時運行
多線程,容許單個任務分爲不一樣的部分運行

10.瞭解音頻播放相關知識

音頻的播放從形式上分爲音頻播放和音樂播放。
音頻播放:一般時間較短,不須要進度控制,和循環控制。使用AudioToolbox.framework。
音樂播放:一般時間較長,須要進行精準控制。使用AVFoundation.framework。

音頻播放
AudioToolbox.framework是基於C語言的框架。
原理:將短音頻註冊的到系統聲音服務(System Sound Service)中。System Sound Service是一種簡單、底層的聲音播放服務。
1.音頻播放時間不能超過30秒。
2.數據必須是PCM或者IMA4格式。
3.音頻格式必須打包成.caf、.aif、wav中的一種。(這是官方說法,實際發現一些.mp3也能夠)。

音樂播放
1.適合播放較大的音頻。
2.能夠對音頻進行精準的播放控制
3.使用AVFoundataion.framework中的AVAudioPlayer來實現。
使用:
1.初始化AVAudioPlayer對象,一般是指定本地文件路徑
2.設置播放器屬性,例如重複次數,音量大小等。
3.調用play方法播放。

注意:AVAudioPlayer一次只能播放一個音頻文件,全部的上一曲和下一曲都是經過建立多個AVAudioPlayer來實現的。

 

11.瞭解視頻播放相關知識

Apple已經爲咱們提供了多種方法來實現視頻播放,包括MPMoviePlayerController,MPMoviePlayerViewController,AVPlayer,AVPlayerViewController等。而值得注意的是,上述的MPMoviePlayerController與MPMoviePlayerViewController在iOS9.0以後被棄用。下面是四種播放方式的區別:

11.理解OC中的反射機制
  1. class反射:經過類名字符串實例化對象
Class class = NSClassFromString(@「Student」); Student *student = [[class alloc] init]; 
  1. 類名轉化爲字符串
Class class = [student class]; NSString *calssName = NSStringFromClass(class); 
  1. SEL的反射
SEL selector = =NSSelectorFromClass(@「setName」); [stu performSelector:selector withObject:nil]; 
  1. 經過方法字符串形式實例化方法
NSStringFromSelector(@selector *( 「setName:」));

12.理解一個對象被建立須要的三個步驟

開闢內存空間
初始化參數
返回內存地址值

 

13.layoutSubView什麼時候調用

一、 初始化方法事不會調用
二、滾動UIScrollview觸發
三、旋轉屏幕時觸發
四、改變View的值時候觸發,前提是frame改變了
五、改變UIView的大小時觸發

14.理解NSOperationQueue

NSOperationQueue是存放NSOPeration的集合類,能夠參考JAVA中的線程和線程池的概念。
雖然說是queue,但並非隊列的意思,並不遵照先進先出。
因此咱們能夠理解爲Pool ,即線程池。

15.理解OC是動態運行時語言

OC將數據、對象類型的肯定從編譯階段推遲到了運行時。實現這一操做的基礎是面嚮對象語言的多態特性。
這裏面有有兩個關鍵字:運行時和多態
運行時:運行時機制使咱們知道運行的時候才肯定一個對象的類型、以及調用該類別對象指定的方法。
多態:不一樣的對象以本身的方式來響應相同的消息。子類的指針能夠賦值給父類。

16.GCD的queue、main queue中執行的代碼必定是在main thread麼?

queue中所執行的代碼不必定在main thread中。若是queue是在主線程中建立的,那麼所執行的代碼就是在主線程中執行。若是是在子線程中建立的,那麼就不會在main thread中執行。
上述說法並不徹底正確,queue中所執行的代碼不必定在主線程是對的,可是隊列Queue中執行的任務是在否在主線程與建立隊列所在的線程並沒有關係。

對於這個問題,首先總結幾個知識點:
1.iOS中獲取隊列的三種方式:
主線程隊列
主線程隊列爲串行隊列,和主線程綁定。同普通串行隊列同樣,隊列中任務一次只能執行一個,可是隊列中全部任務都在主線程中執行(通過測試,即便是異步添加的任務,也沒有建立新的線程)。

全局隊列
系統全局隊列爲併發隊列,根據不一樣的優先級(HIGH、DEFAULT、LOW、BACKGROUND)有四個。

自定義隊列
系統提供方法,能夠自定義建立串行和並行隊列。

2.同步與異步,串行與並行
同步與異步:決定可不能夠開啓新的線程
同步:在當前線程當即執行添加的任務,不具有開啓新線程的能力。
異步:在新的線程中執行任務,具有開啓新線程的能力

並行與串行:決定了任務的執行方式
並行:能夠多個任務併發(同時)執行。類型迅雷,多個任務同時開啓下載
串行:一個任務執行完畢後,再執行下一個任務。相似瀏覽器的一個接一個下載

對於這個問題,我使用 代碼測試了使用的狀況以下:
 

 

總結:隊列Queue中執行的任務是在否在主線程與建立隊列所在的線程無關。

判斷一個任務是否是在主線程,咱們能夠首先判斷同步仍是異步,由於異步才具備開啓新線程的能力。然而咱們還須要注意兩點:
1.主線程所在隊列爲串行隊列,添加同步會致使死鎖。
2.並不是全部的異步任務都不在主線程中,主線程隊列中添加異步任務,並不開啓新的線程。

 

17.常見的Http狀態碼有哪些?

302是請求重定向。
500及以上是服務器錯誤,如503表示服務器找不到、3840表示服務器返回無效JSON。
400及以上是請求連接錯誤或者找不到服務器,如常見的404。
200及以上是正確,如常見的是200表示請求正常。
更多參考: Http狀態碼詳細說明

 

18.Runloop和線程的關係?

19.什麼是消息轉發機制,類和分類同時調用一個方法會發生髮生什麼事情?

20.給一個首頁添加一個頭部如何實現?

21.組件之間如何解耦?

22.同步隊列中block中執行異步操做,會發生什麼事情?

23.runtime怎麼理解的?

24.若是分類和原類擁有相同方法會發生什麼事情:

若是分類中有和原有類同名的方法, 會優先調用分類中的方法, 就是說會忽略原有類的方法。因此同名方法調用的優先級爲 分類 > 本類 > 父類。所以在開發中儘可能不要覆蓋原有類;

25.動態庫和靜態庫的區別:

總結

對於細碎知識點的學習,通過了不斷的測試和理解,咱們纔會發現還有太多值得研究的地方。若是有不對的地方我會盡快更正。

 
 
 
 
 
 
 
 
 
 
 
相關文章
相關標籤/搜索