iOS面試題整理

1.談談Object-C的內存管理方式及過程?java

 Objective-C的內存管理主要有三種方式ARC(自動內存計數)、手動內存計數、內存池。ios

 解決方法的話: 誰持有,誰釋放。程序員

咱們以前使用Objective-C中內存管理規則時,每每採用下面的準則
  •    生成對象時,使用autorelease
  •    對象代入時,先autorelease後再retain
  •    對象在函數中返回時,使用return [[object retain] autorelease];

2.#import和#include的區別,@class表明什麼?數組

@class通常用於頭文件中須要聲明該類的某個實例變量的時候用到,在m文件中仍是須要使用#import服務器

而#import比起#include的好處就是不會引發重複包含網絡

這兩種的方式的區別在於:多線程

 一、#import方式會包含被引用類的全部信息,包括被引用類的變量和方法;@class方式只是告訴編譯器在A.h文件中 B *b 只是類的聲明,具體這個類裏有什麼信息,這裏不須要知道,等實現文件中真正要用到時,纔會真正去查看B類中信息;併發

 二、使用@class方式因爲只須要只要被引用類(B類)的名稱就能夠了,而在實現類因爲要用到被引用類中的實體變量和方法,因此須要使用#importl來包含被引用類的頭文件;app

 三、經過上面2點也很容易知道在編譯效率上,若是有上百個頭文件都#import了同一 個文件,或者這些文件依次被#improt(A->B, B->C,C->D…),一旦最開始的頭文件稍有改動,後面引用到這個文件的全部類都須要從新編譯一遍,這樣的效率也是可想而知的,而相對來 講,使用@class方式就不會出現這種問題了;框架

 四、對於循環依賴關係來講,比方A類引用B類,同時B類也引用A類,

當程序運行時,編譯會報錯, 

由上可知,@class是放在interface中的,只是在引用一個類,將這個被引用類做爲一個類型,在實現文件中,若是須要引用到被引用類的實體變量或者方法時,還須要使用#import方式引入被引用類。

因此,通常來講,@class是放在interface中的,只是爲了在interface中引用這個類,把這個類做爲一個類型來用的。 在實現這個接口的實現類中,若是須要引用這個類的實體變量或者方法之類的,仍是須要import在@class中聲明的類進來.

 

@class

 

一個.h聲明幾個類時,互相使用時。

@class

@interface A

{

  B *B;

}

@interface B{}

3.Object-C有私有方法嗎?私有變量呢

Objective-C中的類自己並無私有方法這個概念,聲明在 .h 文件中的方法都是公有的。不過,要想實現私有方法的效果仍是有辦法的,就是用Category。

// Hello.h

 

#import <Cocoa/Cocoa.h>
@interface Hello : NSObject {
    //變量聲明
}
// 方法聲明
@end
//




// Hello.m
#import "Hello.h"
@interface Hello () //=>此處Hello命名一致,後邊跟括號
//=>@property (某種) aType ivarName ; 可實現私有變量

 

// 私有方法聲明

- (void)test;
@end

@implementation Hello
// 私有方法實現

 

//=>@synthesize ivarName; 有私有變量的話

 

- (void)test {
// ..
}
// 方法實現
@end
在上面這個例子中,test 就是 Hello 類的「私有方法」了。再次證實,Category這個東東真的很強大~

 

4.Object-C有多繼承嗎?沒有的話用什麼代替?cocoa 中全部的類都是NSObject 的子類 

沒有,用1.消息轉發  2.delegate和protocol  3.類別  

5.淺拷貝和深拷貝區別是什麼
簡單的來講就是,在有指針的狀況下,淺拷貝只是增長了一個指針指向已經存在的內存,而深拷貝就是增長一個指針而且申請一個新的內存,使這個增長的指針指向這個新的內存,採用深拷貝的狀況下,釋放內存的時候就不會出如今淺拷貝時重複釋放同一內存的錯誤   retain +1 淺拷貝  copy 深拷貝
6.C和obj-c 如何混用
7. Objective-C中類別和類擴展的區別。

答案:category和extensions的不一樣在於後者能夠添加屬性。另外後者添加的方法是必需要實現的。

extensions能夠認爲是一個私有的Category。

 分類和類擴展的類似之處是: 均可覺得類添加一個額外的方法

 不一樣之處在於:要添加額外方法,分類必須在第一個@interface中聲明方法,而且在@implementation中提供實現,否則運行時出錯。而類擴展,你添加的方法是一個required API,若是不去實現,編譯器會警告,並且這個方法的聲明能夠不在第一個@interface中去聲明。

 
八、堆和棧什麼區別?

  答: 管理方式:對於棧來說,是由編譯器自動管理,無需咱們手工控制;對於堆來講,釋放工做由程序員控制,容易產生memory leak。

九、數組和鏈表什麼區別?

  答: 數組是將元素在內存中連續存放,因爲每一個元素佔用內存相同,能夠經過下標迅速訪問數組中任何元素。

       鏈表剛好相反,鏈表中的元素在內存中不是順序存儲的,而是經過存在元素中的指針聯繫到一塊兒。 

十、delegate和notification什麼區別,什麼狀況使用?

delegate 一對一

notification 一對多

 delegate的命名要準確,儘可能看名字就知道用法。delegate和通知有的用法有些象,可是前者是單對單的,後者是單對多的狀況。

注意:在dealloc要把delegate至爲nil,還有就是delegate設置屬性的時候要用assign,不要用retain。

11

assign: 簡單賦值,不更改索引計數
copy: 創建一個索引計數爲1的對象,而後釋放舊對象
retain:釋放舊的對象,將舊對象的值賦予輸入對象,再提升輸入對象的索引計數爲1 

 

12.兩個controller傳值,

通常的傳值使用簡單的賦值,

你能夠在B裏面聲明一個屬性,在A裏面建立B的時候,將B的屬性賦值便可

若當異步操做(通常耗時的或網絡請求用異步)時,能夠用一下方法,, 或   block

想到四個途徑:
1)使用代理
2)使用通知notification
3)使用NSUserdefault
4)使用全局變量,如在appdelegate裏面定義一個變量用於傳值

NSNotification

  我的以爲用這個東西在不一樣的viewcontroller間傳東西很方便的

  發消息

  [[NSNotificationCenter defaultCenter] postNotificationName:@"popView"/*消息名字,在添加監聽時會用到*/       object:@"ShowHomeLineViewController"/*傳的參數,多個參數就能夠用數組啦*/];

  收消息

  一、添加監聽:

  [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(Show:)/*收到消息後的響應函數*/ name:@"popView"/*消息名字,在發消息時  指定的*/ object:nil];

  二、消息處理(實現前面的Show:函數)

  -(void)Show:(NSNotification*)notification

  {

  NSString* str = (NSString*)[notification object];//這裏取出剛剛從過來的字符串

  }

  三、不要忘記移除監聽

  [[NSNotificationCenter defaultCenter] removeObserver:self name:@"popView" object:nil];

 十一、同步請求和異步請求什麼區別?

答: 發送同步請求,程序將中止用戶交互,直至服務器返回數據完成,才能夠進行下一步操做,

      異步請求不會阻塞主線程,而會創建一個新的線程來操做,用戶發出異步請求後,依然能夠對UI進行操做,程序能夠繼續運行。

十二、iOS中的多線程操做、多線程方式

 iOS 提供了方便的多線程調用機制: NSOperation 和 NSOperationQueue 。它的使用方法也很簡單,

通常都是將NSOperation對象加入到NSOperationQueue隊列中,加入後隊列就開始處理,知道任務操做完成。

1三、UIViewController的生命週期

答: 當一個視圖控制器被建立,並在屏幕上顯示的時候。 代碼的執行順序 
       // 視圖顯示在屏幕上的順序

      一、 alloc                     建立對象,分配空間。

    二、init (initWithNibName)     初始化對象,初始化數據。

    三、loadView                    從nib載入視圖, 這一步不須要去幹涉。除非沒有使用xib文件建立視圖。

    四、viewDidLoad                 加載完畢,能夠進行自定義數據以及動態建立其餘控件。

    五、viewWillAppear              視圖將出如今屏幕以前,立刻這個視圖即將顯示在屏幕上。

    六、viewDidAppear               視圖已在屏幕上渲染完成。

    // 視圖將被從屏幕上移除的順序

    一、viewWillDisappear           視圖將被從屏幕上移除以前執行。

    二、viewDidDisappear            視圖已經被從屏幕上移除。

    三、dealloc                     視圖被銷燬,此時須要在init和viewDidLoad中建立的對象進行釋放。

    四、viewDidUnload               出現內存警告在內存不足時執行,並對全部非當前顯示的controller執行。

iOS6中,viewDidUnload回調方法被Deprecated掉了。查看蘋果的文檔,能夠看到以下的說明。

 

dealloc方法

viewDidUnloaddealloc方法沒有關聯,dealloc仍是繼續作它該作的事情

 

看到如下的代碼

- (void)viewDidUnload {

self.detailViewController = nil; 

self.languageNames = nil; 

self.languageCodes = nil;

}

- (void)dealloc {

[detailViewController release];

 [languageNames release]; 

[languageCodes release]; 

[super dealloc];

}

 

若是是先調用viewDidUnload後再調用dealloc, 那麼languageNames都已是nil了,再掉release有什麼意義呢?

緣由彷佛是,對一個viewcontroller來講,它的數據的初始化在init中,而它管理的view採用了lazy load的方式,也就是有須要的時候纔會載入,因此跟view相關的數據能夠在viewDidLoad(也就是在view被載入的時候)進行初始化。當內存緊張的時候, ios會銷燬點一些view,經過調用viewDidUnload (裏面通常也只是把跟view相關的數據設爲nil, 但這個時候viewcontroller自己還在,因此它的dealloc不會被調用,除非是到了viewcontroller也被銷燬的時候

1四、iOS數據持久化方式

    答: 四種:屬性列表、對象歸檔、SQLite3和Core Data

15.實例方法跟類方法

16.weak strong retain

17.Object C中建立線程的方法是什麼?若是在主線程中執行代碼,方法是什麼?若是想延時執行代碼、方法又是什麼?

 答: 線程建立有三種方法:使用NSThread建立、使用 GCD的dispatch、使用子類化的NSOperation,而後將其加入NSOperationQueue;在主線程執行代碼,方法是 performSelectorOnMainThread,若是想延時執行代碼能夠用performSelector:onThread:withObject:waitUntilDone: 

 

18.

       另外:atomic和nonatomic用來決定編譯器生成的getter和setter是否爲原子操做。在多線程環境下,原子操做是必要的,不然有可能引發錯誤的結果。
       加了atomic,setter函數會變成下面這樣:
       if (property != newValue) {
       [property release];
       property = [newValue retain];
       }

19. 單件實例是什麼

 答:  Foundation 和 Application Kit 框架中的一些類只容許建立單件對象,即這些類在當前進程中的惟一實例。

       舉例:NSFileManager 和NSWorkspace 類在使用時都是基於進程進行單件對象的實例化。

       當向這些類請求實例的時候,它們會向您傳遞單一實例的一個引用,若是該實例還不存在,則首先進行實例的分配 和初始化。

 

27.類別的做用?繼承和類別在實現中有何區別? 
 答: category 能夠在不獲悉,不改變原來代碼的狀況下往裏面添加新的方法,只能添加,不能刪除修改。

      而且若是類別和原來類中的方法產生名稱衝突,則類別將覆蓋原來的方法,由於類別具備更高的優先級。 類別主要有3個做用:

      (1)將類的實現分散到多個不一樣文件或多個不一樣框架中。

      (2)建立對私有方法的前向引用。

      (3)向對象添加非正式協議。  

      繼承能夠增長,修改或者刪除方法,而且能夠增長屬性。

 28.類別和類擴展的區別。 
 答: category和extensions的不一樣在於 後者能夠添加屬性。另外後者添加的方法是必需要實現的。 extensions能夠認爲是一個私有的Category。

 

 29.29.KVO and KVC?

 

20.代理的做用

答: 代理的目的是改變或傳遞控制鏈。容許一個類在某些特定時刻通知到其餘類,而不須要獲取到那些類的指針。能夠減小框架複雜度。 另一點,代理能夠理解爲java中的回調監聽機制的一種相似。

32.frame和bounds有什麼不一樣? 
答: frame指的是:該view在父view座標系統中的位置和大小。(參照點是父親的座標系統) bounds指的是:該view在自己座標系統中 的位置和大小。(參照點是自己座標系統)

 
33.方法和選擇器有何不一樣? 
答: selector是一個方法的名字,method是一個組合體 。
35.ARC自動引用技術
答: 1.ARC是編譯特性,不是運行時特性,只是在編譯的時候,編譯器會自動加上釋放代碼 
    2.不能調用release、retain、autorelease、retainCount 
    3.dealloc注意 
     1> 不能在dealloc中調用[super dealloc] 
     2> 不能在dealloc中釋放資源 
    4.@property 參數說明 
    1> retain 改成 strong 
    2> 基本數據類型(int\float)仍是用assign 
    3> copy 仍是 copy 
    4> 若是2個對象循環引用,一端用strong,一端用weak 
    5> weak是用在對象上,weak其實做用跟assign至關 
    5.ARC中只容許使用經過@autoreleasepool {}建立自動釋放池
34.iOS多線程GCD

35.

進程和線程的主要差異在於它們是不一樣的操做系統資源管理方式。進程有獨立的地

址空間,一個進程崩潰後,在保護模式下不會對其它進程產生影響,而線程只是一

個進程中的不一樣執行路徑。線程有本身的堆棧和局部變量,但線程之間沒有單獨的

地址空間,一個線程死掉就等於整個進程死掉,因此多進程的程序要比多線程的程

序健壯,但在進程切換時,耗費資源較大,效率要差一些。但對於一些要求同時進

行而且又要共享某些變量的併發操做,只能用線程,不能用進程。

 

36.

爲何不少內置的類,如TableViewController的delegate的屬性是assign不是retain?

循環引用 全部的引用計數系統,都存在循環應用的問題。例以下面的引用關係:     •    對象a建立並引用到了對象b.     •    對象b建立並引用到了對象c.     •    對象c建立並引用到了對象b. 這時候b和c的引用計數分別是2和1。當a再也不使用b,調用release釋放對b的全部權,由於c還引用了b,因此b的引用計數爲1,b不會被釋放。b不釋放,c的引用計數就是1,c也不會被釋放。今後,b和c永遠留在內存中。 這種狀況,必須打斷循環引用,經過其餘規則來維護引用關係。好比,咱們常見的delegate每每是assign方式的屬性而不是retain方式 的屬性,賦值不會增長引用計數,就是爲了防止delegation兩端產生沒必要要的循環引用。若是一個UITableViewController 對象a經過retain獲取了UITableView對象b的全部權,這個UITableView對象b的delegate又是a, 若是這個delegate是retain方式的,那基本上就沒有機會釋放這兩個對象了。本身在設計使用delegate模式時,也要注意這點。

相關文章
相關標籤/搜索