iOS面試題總結

1.爲何說Objective-C是一門動態的語言?

1.object-c類的類型和數據變量的類型都是在運行是肯定的,而不是在編譯時肯定。例如:多態特性,咱們可使用父類對象來指向子類對象,而且能夠用來調用子類的方法。運行時(runtime)特性,咱們能夠動態的添加方法,或者替換方法。html

2.講一下MVC和MVVM,MVP?

MVC:簡單來講就是,邏輯、試圖、數據進行分層,實現解耦。
MVVM:是Model-View-ViewMode模式的簡稱。由視圖(View)、視圖模型(ViewModel)、模型(Model)三部分組成.比MVC更加釋放控制器臃腫,將一部分邏輯(耗時,公共方法,網絡請求等)和數據的處理等操做從控制器裏面搬運到ViewModel
MVVM的特色:git

  1. 低耦合。View能夠獨立於Model變化和修改,一個ViewModel能夠綁定到不一樣的View上,當View變化的時候Model能夠不變,當Model變化的時候View也能夠不變。
  1. 可重用性。能夠把一些視圖的邏輯放在ViewModel裏面,讓不少View重用這段視圖邏輯。
  1. 獨立開發。開發人員能夠專一與業務邏輯和數據的開發(ViewModel)。設計人員能夠專一於界面(View)的設計。
  1. 可測試性。能夠針對ViewModel來對界面(View)進行測試

MVP:本小編沒有接觸,但願能夠獲得你們的幫助。能夠在下面留言。github

3.爲何代理要用weak?代理的delegate和dataSource有什麼區別?block和代理的區別?

代理是使用weak來修飾的。1.使用weak是爲了不循環引用。2.當使用weak修飾的屬性,當對象釋放的時候,系統會對屬性賦值nil,object-c有個特性就是對nil對象發送消息也就是調用方法,不會cash。
delegate:表示代理,代理可讓A對象通知B對象,我(A)發生的變化,前提B遵循了A的代理,而且實現了A的代理方法。
dataSource:表示數據源,若是A對象聲明瞭數據源,當咱們建立A對象的時候,咱們就該實現數據源,來告訴A,他所須要的一些數據。例如:tableView數據源方法,須要告訴它,我要實現幾組cell,每組cell多少行cell,實現的cell什麼樣式,什麼內容
一樣delegatedataSource,都是可使用requireoptional來修飾的。面試

代理和Block的區別

相同點:代理和Block大可能是咱們均可以用來作倒序傳值的。咱們都得注意避免循環引用。
不一樣點:代理使用weak修飾,代理必須先聲明方法。當咱們調用代理的時候要判斷是否已經實現。
block:使用的是copy來修飾,block保存的是一段代碼,其實也就是一個函數。當咱們調用block的時候要判斷是否已經實現。sql

4.屬性的實質是什麼?包括哪幾個部分?屬性默認的關鍵字都有哪些?@dynamic關鍵字和@synthesize關鍵字是用來作什麼的?

屬性是描述類的特徵,也就是具有什麼特性。三個部分,帶下劃線的成員變量,get、setter方法。
默認關鍵字:readwrite,assign, atomic;
@dynamic :修飾的屬性,其getter和setter方法編譯器是不會自動幫你生成。必須本身是實現的。
@synthesize:修飾的屬性,其getter和setter方法編譯器是會自動幫你生成。沒必要本身實現,能夠指定與屬性相對應的成員變量。數據庫

5.屬性的默認關鍵字是什麼?

默認關鍵字:readwrite,assign, atomic;數組

6.NSString爲何要用copy關鍵字,若是用strong會有什麼問題?(注意:這裏沒有說用strong就必定不行。使用copy和strong是看狀況而定的

衆所周知,咱們知道,可變類型(NSMutableArray,NSMutableString等)是不可邊類型(NSString,NSArray等)的子類,由於多態的緣由,咱們可使用賦值指向子類對象,也就是咱們可使用不可邊類型去接受可變類型。
1.當咱們使用strong修飾A不可邊類型的時候,而且使用B可變類型給A賦值,再去修改可變類型B值的時候,A所指向的值也會發生改變。引文strong只是讓建立的對象引用計數器+1,並返回當前對象的內容地址,當咱們修改B指向的內容的時候,A指向的內容也一樣發生了改變,由於他們指向的內存地址是相同的,是一分內容。
2.當咱們使用copy修飾A不可邊類型的時候,而且使用B可變類型給A賦值,再去修改可變類型B值的時候,A所指向的值不會發生改變。由於當時用copy的修飾的時候,會拷貝一分內容出來,而且返回指針給A,當咱們修改B指向的內容的時候,A指向的內容是沒有發生改變的。由於A指向的內存地址和B指向的內存地址是不相同的,是兩分內容
3.copy修飾不可邊類型(NSString,NSArray等)的時候,且使用不可邊類型進行賦值,表示淺拷貝,只拷貝一份指針,和strong修飾同樣,當修飾的是可變類型(NSMutableArray,NSMutableString等)的時候,表示深拷貝,直接拷貝新一分內容,到內存中。表示兩分內容。緩存

7.如何令本身所寫的對象具備拷貝功能?

必須遵循nscopying協議,若是想實現可變和不可邊拷貝時,必須同時遵循nscopingnsmutablecoping協議。而且實現
- (id)copyWithZone:(NSZone *)zone;安全

8.可變集合類 和 不可變集合類的 copy 和 mutablecopy有什麼區別?若是是集合是內容複製的話,集合裏面的元素也是內容複製麼?

可變使用copy表示深拷貝,不可變集合類使用copy的時候是淺拷貝。
可變集合類使用mutablecopy表示深拷貝,不可變集合類使用copy的時候是淺拷貝。
關於容器實現copy 或 metableCopy ,容器內元素默認都是 指針拷貝,不是內容複製。網絡

9.爲何IBOutlet修飾的UIView也適用weak關鍵字?

在xib或者Sb拖控件時,其實控件就加載到了父控件的subviews數組裏面,進行了強引用,即便使用了weak,也不形成對象的釋放。

10.nonatomic和atomic的區別?atomic是絕對的線程安全麼?爲何?若是不是,那應該如何實現?

nonatomic:表示非原子,不安全,可是效率高。
atomic:表示原子行,安全,可是效率定。
atomic:不能絕對保證線程的安全,當多線程同時訪問的時候,會形成線程不安全。可使用線程鎖來保證線程的安全。

11.UICollectionView自定義layout如何實現?

實現一個自定義layout的常規作法是繼承UICollectionViewLayout類,而後重載下列方法:

-(CGSize)collectionViewContentSize
返回collectionView的內容的尺寸
-(NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
返回rect中的全部的元素的佈局屬性
返回的是包含UICollectionViewLayoutAttributes的NSArray
UICollectionViewLayoutAttributes能夠是cell,追加視圖或裝飾視    圖的信息,經過不一樣的UICollectionViewLayoutAttributes初始化方法能夠獲得不一樣類型的UICollectionViewLayoutAttributes:
   layoutAttributesForCellWithIndexPath:
   layoutAttributesForSupplementaryViewOfKind:withIndexPath:
layoutAttributesForDecorationViewOfKind:withIndexPath:
  -(UICollectionViewLayoutAttributes )layoutAttributesForItemAtIndexPath:(NSIndexPath )indexPath
返回對應於indexPath的位置的cell的佈局屬性
-(UICollectionViewLayoutAttributes )layoutAttributesForSupplementaryViewOfKind:(NSString )kind atIndexPath:(NSIndexPath *)indexPath
返回對應於indexPath的位置的追加視圖的佈局屬性,若是沒有追加視圖可不重載
-(UICollectionViewLayoutAttributes * )layoutAttributesForDecorationViewOfKind:(NSString)decorationViewKind atIndexPath:(NSIndexPath )indexPath
返回對應於indexPath的位置的裝飾視圖的佈局屬性,若是沒有裝飾視圖可不重載
-(BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
當邊界發生改變時,是否應該刷新佈局。若是YES則在邊界變化(通常是scroll到其餘地方)時,將從新計算須要的佈局信息。

12.用StoryBoard開發界面有什麼弊端?如何避免?

使用簡單邏輯頁面的跳轉是可使用sb的,開發比較塊。
可是SB對於邏輯項目比較複雜的時候,開發起來比較慢。不適合多人合做開發;也不利於版本的梗系和後期的維護。使用sb在項目變異編譯的時候,也都會直接加載到內存中,形成內存的浪費。
可使用xib來代替,編輯複雜邏輯界面時候可使用純碼編寫。

13.進程和線程的區別?同步異步的區別?並行和併發的區別?

進程:是具備必定獨立功能的程序關於某個數據集合上的一次運行活動,進程是系統進行資源分配和調度的一個獨立單位.
線程:是進程的一個實體,是CPU調度和分派的基本單位,它是比進程更小的能獨立運行的基本單位.線程本身基本上不擁有系統資源,只擁有一點在運行中必不可少的資源(如程序計數器,一組寄存器和棧),可是它可與同屬一個進程的其餘的線程共享進程所擁有的所有資源.
同步:阻塞當前線程操做,不能開闢線程。
異步:不阻礙線程繼續操做,能夠開闢線程來執行任務。
併發:當有多個線程在操做時,若是系統只有一個CPU,則它根本不可能真正同時進行一個以上的線程,它只能把CPU運行時間劃分紅若干個時間段,再將時間 段分配給各個線程執行,在一個時間段的線程代碼運行時,其它線程處於掛起狀。.這種方式咱們稱之爲併發(Concurrent)。
並行:當系統有一個以上CPU時,則線程的操做有可能非併發。當一個CPU執行一個線程時,另外一個CPU能夠執行另外一個線程,兩個線程互不搶佔CPU資源,能夠同時進行,這種方式咱們稱之爲並行(Parallel)。
區別:併發和並行是即類似又有區別的兩個概念,並行是指兩個或者多個事件在同一時刻發生;而併發是指兩個或多個事件在同一時間間隔內發生。在多道程序環境下,併發性是指在一段時間內宏觀上有多個程序在同時運行,但在單處理機系統中,每一時刻卻僅能有一道程序執行,故微觀上這些程序只能是分時地交替執行。假若在計算機系統中有多個處理機,則這些能夠併發執行的程序即可被分配到多個處理機上,實現並行執行,即利用每一個處理機來處理一個可併發執行的程序,這樣,多個程序即可以同時執行。

14.線程間通訊?

當使用dispath-async函數開闢線程執行任務的完成時,咱們須要使用dispatch_async(dispatch_get_main_queue(), ^{ });函數會到主線程內刷新UI。並完成通訊

15.GCD的一些經常使用的函數?(group,barrier,信號量,線程同步)

咱們使用隊列組來開闢線程時,隊列組中的隊列任務是併發,當全部的隊列組中的全部任務完成時候,才能夠調用隊列組完成任務。

/**建立本身的隊列*/
dispatch_queue_t dispatchQueue = dispatch_queue_create("ted.queue.next", DISPATCH_QUEUE_CONCURRENT);
/**建立一個隊列組*/
dispatch_group_t dispatchGroup = dispatch_group_create();
/**將隊列任務添加到隊列組中*/
dispatch_group_async(dispatchGroup, dispatchQueue, ^(){
    NSLog(@"dispatch-1");
});
   /**將隊列任務添加到隊列組中*/
dispatch_group_async(dispatchGroup, dispatchQueue, ^(){
    NSLog(@"dspatch-2");
});
  /**隊列組完成調用函數*/
dispatch_group_notify(dispatchGroup, dispatch_get_main_queue(), ^(){
    NSLog(@"end");
})

barrier:表示柵欄,當在併發隊列裏面使用柵欄時候,柵欄以前的併發任務開始併發執行,執行完畢後,執行柵欄內的任務,等柵欄任務執行完畢後,再併發執行柵欄後的任務。

dispatch_queue_t concurrentQueue = dispatch_queue_create("my.concurrent.queue", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(concurrentQueue, ^(){
    NSLog(@"dispatch-1");
});
dispatch_async(concurrentQueue, ^(){
    NSLog(@"dispatch-2");
});
dispatch_barrier_async(concurrentQueue, ^(){
    NSLog(@"dispatch-barrier"); 
});
dispatch_async(concurrentQueue, ^(){
    NSLog(@"dispatch-3");
});
dispatch_async(concurrentQueue, ^(){
    NSLog(@"dispatch-4");
});

信號量:Semaphore是經過‘計數’的方式來標識線程是不是等待或繼續執行的。信號量

dispatch_semaphore_create(int) // 建立一個信號,並初始化信號的計數大小
/* 等待信號,而且判斷信號量,若是信號量計數大於等於你建立時候的信號量的計數,就能夠經過,繼續執行,而且將你傳入的信號計數減1,
 * 若是傳入的信號計數小於你建立的計數,就表示等待,等待信號計數的變化
 *  若是等待的時間超過你傳入的時間,也會繼續下面操做
 *   第一個參數:semaphore 表示信號量
 *   第二個參數:表示等待的時間
 *    返回int 若是傳入的信號計數大於等於你建立信號的計數時候,返回0.  反之,返回的不等於0
 */
 int result = dispatch_semaphore_wait(dispatch_semaphore_t  semaphore,time outTime);// 表示等待,也是阻礙線程
// 表示將信號技術+1
dispatch_semaphore_signl(dispatch_semaphore_t semaphore);

實現線程的同步的方法:串行隊列,分組,信號量。也是可使用併發隊列。

//加入隊列
dispatch_async(concurrentQueue, ^{
    //1.先去網上下載圖片
    dispatch_sync(concurrentQueue, ^{
       
    });
    //2.在主線程展現到界面裏
    dispatch_sync(dispatch_get_main_queue(), ^{

    });
});

16.如何使用隊列來避免資源搶奪?

當咱們使用多線程來訪問同一個數據的時候,就有可能形成數據的不許確性。這個時候我麼可使用線程鎖的來來綁定。也是可使用串行隊列來完成。如:fmdb就是使用FMDatabaseQueue,來解決多線程搶奪資源。

17.數據持久化的幾個方案(fmdb用沒用過)

持久化方案:
plist,存儲字典,數組比較好用
preference:偏好設置,實質也是plist
NSKeyedArchiver:歸檔,能夠存儲對象
sqlite:數據庫,常用第三方來操做,也就是fmdb
coreData:也是數據庫儲存,蘋果官方的

18.說一下appdelegate的幾個方法?從後臺到前臺調用了哪些方法?第一次啓動調用了哪些方法?從前臺到後臺調用了哪些方法?

1029210 (1).gif
1029210 (1).gif

19.NSCache優於NSDictionary的幾點?

1.nscache 是能夠自動釋放內存的。
2.nscache是線程安全的,咱們能夠在不一樣的線程中添加,刪除和查詢緩存中的對象。
3.一個緩存對象不會拷貝key對象。

20.知不知道Designated Initializer?使用它的時候有什麼須要注意的問題?

我的理解:初始化函數,若是你想自定義初始化函數時,也是必需要初始化父類,以來保證能夠繼承父類的一些方法或者屬性。
Designated Initializer

21.實現description方法能取到什麼效果?

description是nsobject的一個實例的方法,返回的是一個nsstring。當咱們使用nslog打印的時候,打印出來的通常都是對象的內存地址,若是咱們實現description方法時,咱們就可使用nslog打印對象的時候,咱們能夠把它裏面的屬性值和內存地址一塊兒打印出來.打印什麼,就是看你寫什麼了。

-(NSString *)description{  
      NSString * string = [NSString stringWithFormat:@"<Person:內存地址:%p name = %@ age = %ld>",self,self.name,self.age];  
      return string;      
}

22.objc使用什麼機制管理對象內存?

使用內存管理計數器,來管理內存的。當內存管理計數器爲0的時候,對象就會被釋放。

中級

Block

1.block的實質是什麼?一共有幾種block?都是什麼狀況下生成的?

block:本質就是一個object-c對象.
block:存儲位置,可能分爲3個地方:代碼去,堆區、棧區(ARC狀況下會自動拷貝到堆區,所以ARC下只能有兩個地方:代碼去、堆區)
代碼區:不訪問棧區的變量(如局部變量),且不訪問堆區的變量(alloc建立的對象),此時block存放在代碼去。
堆區:訪問了處於棧區的變量,或者堆區的變量,此時block存放在堆區。–須要注意實際是放在棧區,在ARC狀況下會自動拷貝到堆區,若是不是ARC則存放在棧區,所在函數執行完畢就回釋放,想再外面調用須要用copy指向它,這樣就拷貝到了堆區,strong屬性不會拷貝、會形成野指針錯區。

2.爲何在默認狀況下沒法修改被block捕獲的變量? __block都作了什麼?

默認狀況下,block裏面的變量,拷貝進去的是變量的值,而不是指向變量的內存的指針。
當使用__block修飾後的變量,拷貝到block裏面的就是指向變量的指針,因此咱們就能夠修改變量的值。

3.模擬一下循環引用的一個狀況?block實現界面反向傳值如何實現?

Person *p = [[Person alloc]init];
[p setPersonBlock:^(NSString *str) {
    p.name = str;
}];

Runtime

1.objc在向一個對象發送消息時,發生了什麼?

根據對象的isa指針找到類對象id,在查詢類對象裏面的methodLists方法函數列表,若是沒有在好到,在沿着superClass,尋找父類,再在父類methodLists方法列表裏面查詢,最終找到SEL,根據idSEL確認IMP(指針函數),在發送消息;

3.何時會報unrecognized selector錯誤?iOS有哪些機制來避免走到這一步?

當發送消息的時候,咱們會根據類裏面的methodLists列表去查詢咱們要動用的SEL,當查詢不到的時候,咱們會一直沿着父類查詢,當最終查詢不到的時候咱們會報unrecognized selector錯誤
當系統查詢不到方法的時候,會調用+(BOOL)resolveInstanceMethod:(SEL)sel動態解釋的方法來給我一次機會來添加,調用不到的方法。或者咱們能夠再次使用-(id)forwardingTargetForSelector:(SEL)aSelector重定向的方法來告訴系統,該調用什麼方法,一來保證不會崩潰。

4.可否向編譯後獲得的類中增長實例變量?可否向運行時建立的類中添加實例變量?爲何?

1.不能向編譯後獲得的類增長實例變量
2.能向運行時建立的類中添加實例變量
解釋:
1.編譯後的類已經註冊在runtime中,類結構體中的objc_ivar_list實例變量的鏈表和instance_size實例變量的內存大小已經肯定,runtime會調用class_setvarlayout或class_setWeaklvarLayout來處理strong weak引用.因此不能向存在的類中添加實例變量
2.運行時建立的類是能夠添加實例變量,調用class_addIvar函數.可是的在調用objc_allocateClassPair以後,objc_registerClassPair以前,緣由同上.

5.runtime如何實現weak變量的自動置nil?

runtime 對註冊的類, 會進行佈局,對於 weak 對象會放入一個 hash 表中。 用 weak 指向的對象內存地址做爲 key,當此對象的引用計數爲0的時候會 dealloc,假如 weak 指向的對象內存地址是a,那麼就會以a爲鍵, 在這個 weak 表中搜索,找到全部以a爲鍵的 weak 對象,從而設置爲 nil。

6.給類添加一個屬性後,在類結構體裏哪些元素會發生變化?

instance_size :實例的內存大小
objc_ivar_list *ivars:屬性列表

RunLoop

1.runloop是來作什麼的?runloop和線程有什麼關係?主線程默認開啓了runloop麼?子線程呢?

runloop:字面意思就是跑圈,其實也就是一個循環跑圈,用來處理線程裏面的事件和消息。
runloop和線程的關係:每一個線程若是想繼續運行,不被釋放,就必須有一個runloop來不停的跑圈,以來處理線程裏面的各個事件和消息。
主線程默認是開啓一個runloop。也就是這個runloop才能保證咱們程序正常的運行。子線程是默認沒有開始runloop的

2.runloop的mode是用來作什麼的?有幾種mode?

model:是runloop裏面的模式,不一樣的模式下的runloop處理的事件和消息有必定的差異。
系統默認註冊了5個Mode:
(1)kCFRunLoopDefaultMode: App的默認 Mode,一般主線程是在這個 Mode 下運行的。
(2)UITrackingRunLoopMode: 界面跟蹤 Mode,用於 ScrollView 追蹤觸摸滑動,保證界面滑動時不受其餘 Mode 影響。
(3)UIInitializationRunLoopMode: 在剛啓動 App 時第進入的第一個 Mode,啓動完成後就再也不使用。
(4)GSEventReceiveRunLoopMode: 接受系統事件的內部 Mode,一般用不到。
(5)kCFRunLoopCommonModes: 這是一個佔位的 Mode,沒有實際做用。
注意iOS 對以上5中model進行了封裝
NSDefaultRunLoopMode;
NSRunLoopCommonModes

3.爲何把NSTimer對象以NSDefaultRunLoopMode(kCFRunLoopDefaultMode)添加到主運行循環之後,滑動scrollview的時候NSTimer卻不動了?

nstime對象是在 NSDefaultRunLoopMode下面調用消息的,可是當咱們滑動scrollview的時候,NSDefaultRunLoopMode模式就自動切換到UITrackingRunLoopMode模式下面,卻不能夠繼續響應nstime發送的消息。因此若是想在滑動scrollview的狀況下面還調用nstime的消息,咱們能夠把nsrunloop的模式更改成NSRunLoopCommonModes

4.蘋果是如何實現Autorelease Pool的?

Autorelease Pool做用:緩存池,能夠避免咱們常常寫relase的一種方式。其實就是延遲release,將建立的對象,添加到最近的autoreleasePool中,等到autoreleasePool做用域結束的時候,會將裏面全部的對象的引用計數器-1.
autorelease

類結構

1.isa指針?(對象的isa,類對象的isa,元類的isa都要說)

在oc中,類也是對象,所屬元類。因此常常說:萬物皆對象

對象的isa指針指向所屬的類
類的isa指針指向了所屬的元類
元類的isa指向了根元類,根元類指向了本身。

AC17D0A0-CB2A-4C23-8430-4BC7A99571CE.png
AC17D0A0-CB2A-4C23-8430-4BC7A99571CE.png

2.類方法和實例方法有什麼區別?

調用的方式不一樣,類方法必須使用類調用,在方法裏面不能調用屬性,類方法裏面也必須調用類方法。存儲在元類結構體裏面的methodLists裏面
實例方法必須使用實例對象調用,能夠在實例方法裏面使用屬性,實例方法也必須調用實例方法。存儲在類結構體裏面的methodLists裏面

3.介紹一下分類,能用分類作什麼?內部是如何實現的?它爲何會覆蓋掉原來的方法?

category:咱們能夠給類或者系統類添加實例方法方法。咱們添加的實例方法,會被動態的添加到類結構裏面的methodList列表裏面。categort

4.運行時能增長成員變量麼?能增長屬性麼?若是能,如何增長?若是不能,爲何?

能夠添加屬性的,但必須咱們實現它的gettersetter方法。可是沒有添加帶下滑線同名的成員變量
可是咱們使用runtime咱們就能夠實現添加成員變量方法以下

- (void)setName:(NSString *)name {
/**
 *  爲某個類關聯某個對象
 *
 *  @param object#> 要關聯的對象 description#>
 *  @param key#>    要關聯的屬性key description#>
 *  @param value#>  你要關聯的屬性 description#>
 *  @param policy#> 添加的成員變量的修飾符 description#>
 */
  objc_setAssociatedObject(self, @selector(name), name,   OBJC_ASSOCIATION_COPY_NONATOMIC);
}
- (NSString *)name {
/**
 *  獲取到某個類的某個關聯對象
 *
 *  @param object#> 關聯的對象 description#>
 *  @param key#>    屬性的key值 description#>
 */
return objc_getAssociatedObject(self, @selector(name));
}

5.objc中向一個nil對象發送消息將會發生什麼?(返回值是對象,是標量,結構體)

• 若是一個方法返回值是一個對象,那麼發送給nil的消息將返回0(nil)。例如:Person * motherInlaw = [ aPerson spouse] mother]; 若是spouse對象爲nil,那麼發送給nil的消息mother也將返回nil。
• 若是方法返回值爲指針類型,其指針大小爲小於或者等於sizeof(void*),float,double,long double 或者long long的整型標量,發送給nil的消息將返回0。
• 若是方法返回值爲結構體,正如在《Mac OS X ABI 函數調用指南》,發送給nil的消息將返回0。結構體中各個字段的值將都是0。其餘的結構體數據類型將不是用0填充的。
• 若是方法的返回值不是上述提到的幾種狀況,那麼發送給nil的消息的返回值將是未定義的。

詳細解答

高級

1.UITableview的優化方法(緩存高度,異步繪製,減小層級,hide,避免離屏渲染)

緩存高度:當咱們建立frame模型的時候,計算出來cell的高度的時候,咱們能夠將cell的高度緩存到字典裏面,以cell的indexpathIdentifier做爲爲key。

NSString *key = [[HeightCache shareHeightCache] makeKeyWithIdentifier:@"YwywProductGradeCell" indexPath:indexPath];
if ([[HeightCache shareHeightCache] existInCacheByKey:key]) {
    return [[HeightCache shareHeightCache] heightFromCacheWithKey:key];
}else{
    YwywProductGradeModelFrame *modelFrame = self.gradeArray[indexPath.row];
    [[HeightCache shareHeightCache] cacheHieght:modelFrame.cellHight key:key];
    return modelFrame.cellHight;
}

異步繪製、減小層級:目前還不是很清楚
hide:我的理解應該是hidden吧,把可能會用到的控件都建立出來,根據不一樣的狀況去隱藏或者顯示出來。
避免離屏渲染:只要不是同時使用邊框/邊框顏色以及圓角的時候,均可以使用layer直接設置。不會形成離屏渲染。

2.有沒有用過運行時,用它都能作什麼?(交換方法,建立類,給新建立的類增長方法,改變isa指針)

交換方式:通常寫在類的+(void)load方法裏面

/** 獲取原始setBackgroundColor方法 */
Method originalM = class_getInstanceMethod([self class], @selector(setBackgroundColor:));
/** 獲取自定義的pb_setBackgroundColor方法 */
Method exchangeM = class_getInstanceMethod([self class], @selector(pb_setBackgroundColor:));
/** 交換方法 */
method_exchangeImplementations(originalM, exchangeM);
建立類:
Class MyClass = objc_allocateClassPair([NSObject class], "Person", 0);
添加方法
/**參數1、類名參數
   2、SEL 添加的方法名字參數
    3、IMP指針 (IMP就是Implementation的縮寫,它是指向一個方法實現的指針,每個方法都有一個對應的IMP)
  參數4、其中types參數爲"i@:@「,按順序分別表示:具體類型可參照[官方文檔](https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html)i 返回值類型int,如果v則表示void@ 參數id(self): SEL(_cmd)@ id(str)
  V@:表示返回值是void 帶有SEL參數 (An object (whether statically typed or typed id))
  */
class_addMethod(Person, @selector(addMethodForMyClass:), (IMP)addMethodForMyClass, "V@:");
添加實例變量
/**參數1、類名參數
  2、屬性名稱參數
  3、開闢字節長度參數
  4、對其方式參數
  5、參數類型 「@」 官方解釋 An object (whether statically typed or typed id) (對象 靜態類型或者id類型) 具體類型可參照[官方文檔](https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html)return: BOOL 是否添加成功
  */
BOOL isSuccess = class_addIvar(Person, "name", sizeof(NSString *), 0, "@");
isSuccess?NSLog(@"添加變量成功"):NSLog(@"添加變量失敗");

3.看過哪些第三方框架的源碼?都是如何實現的?(若是沒有,問一下多圖下載的設計)

4.SDWebImage的緩存策略?

sd加載一張圖片的時候,會先在內存裏面查找是否有這張圖片,若是沒有會根據圖片的md5(url)後的名稱去沙盒裏面去尋找,是否有這張圖片,若是沒有會開闢線程去下載,下載完畢後加載到imageview上面,並md(url)爲名稱緩存到沙盒裏面。

5.AFN爲何添加一條常駐線程?

AFN 目的:就是開闢線程請求網絡數據。若是沒有常住線程的話,就會每次請求網絡就去開闢線程,完成以後銷燬開闢線程,這樣就形成資源的浪費,開闢一條常住線程,就能夠避免這種浪費,咱們能夠在每次的網絡請求都添加到這條線程。

6.KVO的使用?實現原理?(爲何要建立子類來實現)

kvo:鍵值觀察,根據鍵對應的值的變化,來調用方法。
註冊觀察者:addObserver:forKeyPath:options:context:
實現觀察者:observeValueForKeyPath:ofObject:change:context:
移除觀察者:removeObserver:forKeyPath:(對象銷燬,必須移除觀察者)
注意
使用kvo監聽A對象的時候,監聽的本質不是這個A對象,而是系統建立的一箇中間對象NSKVONotifying_A並繼承A對象,而且A對象的isa指針指向的也不是A的類,而是這個NSKVONotifying_A對象
kvo詳解
kvo詳解2

7.KVC的使用?實現原理?(KVC拿到key之後,是如何賦值的?知不知道集合操做符,能不能訪問私有屬性,能不能直接訪問_ivar)

kvc:鍵值賦值,使用最多的即便字典轉模型。利用runtime獲取對象的全部成員變量, 在根據kvc鍵值賦值,進行字典轉模型
setValue: forKey: 只查找本類裏面的屬性
setValue: forKeyPath:會查找本類裏面屬性,沒有會繼續查找父類裏面屬性。
kvc詳解

項目

1.有已經上線的項目麼?

2.項目裏哪一個部分是你完成的?(找一個亮點問一下如何實現的)

3.開發過程當中遇到過什麼困難,是如何解決的?

學習

4.遇到一個問題徹底不能理解的時候,是如何幫助本身理解的?舉個例子?

5.有看書的習慣麼?最近看的一本是什麼書?有什麼心得?

6.有沒有使用一些筆記軟件?會在多平臺同步以及多渠道採集麼?(若是沒有,問一下是如何複習知識的)

7.有沒有使用清單類,日曆類的軟件?(若是沒有,問一下是如何安排,計劃任務的)

8.日常看博客麼?有沒有本身寫過?(若是寫,有哪些收穫?若是沒有寫,問一下不寫的緣由)

以上就是所有的面試題,後面的面試題,就該根據我的的狀況來回答了。
以上的面試回答,有的是根據本身的知識儲備回答,有的也是小編百度的。
以上的回答也不知道對與錯,歡迎你們發表本身的見解

做者:七秒記憶的魚兒連接:http://www.jianshu.com/p/f9eb6b315c08來源:簡書著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處。
相關文章
相關標籤/搜索