天天看點

iOS面試現場,筆試提高題詳解

現在已經不斷有網友發我他們在面試中遇到的面試題,這是一位程式媛前面在面試中遇到的問題

前面兩個過于基礎,從提高題開始分享;個人見解,勿噴

代理的的是改變或傳遞控制鍊。允許個類在某些特定時刻通知到其他類,而需要擷取到那些類的指針。可以減少架構複雜度。

什麼是代理?

代理是種通的設計模式,代理主要由三部分組成

一、協定:用來指定代雙方可以做麼,必須做麼;

二、代:根據指定的協定,完成委托需要實作的功能;

三、委托:根據指定的協定,指定代理去完成麼功能。

代理的實作流程

在iOS中代的本質就是代理對象記憶體的傳遞和操作,我們在委托類設定代理對象後,實際上隻是一個id類型的指針将代理對象進了一個弱引。委托讓代理方執操作,實際上是在委托類中向這個id類型指針指向的對象發送消息,這個id類型指針指向的對象,就是代理對象。

代理的記憶體管理

使代理如果聲明的對,會造成循環引的問題。般會

weak

修飾,

strong

修飾會造成循環引問題,

assign

修飾會造成

crash

代理與其他iOS中消息傳遞的式的對

通知:在iOS中由通知中進消息接收和消息播,是種對多的消息傳遞式。

代理:是種通的設計模式,iOS中對代理持的很好,由代理對象、委托者、協定三部分組成。

Block

:

iOS4.0

中引的種回調法,可以将回調處理代碼直接寫在

block

代碼塊中,看起來邏輯清晰代碼整。

target action

:通過将對象傳遞到另個類中,在另個類中将該對象當做

target

的式,來調該對象法,從記憶體度來說和代理類似。

KVO

NSObject

Category-NSKeyValueObserving

,通過屬性監聽的式來監測某個值的變化,當值發變化時調

KVO

的回調法。

代理與

block

的對

1.多個消息傳遞,應該使delegate。在有多個消息傳遞時,

delegate

實作更合适,看起來也更清晰。

block

就不太好了,這個時候

block

反而便于維護,且看起來常臃腫,很别扭。例如

UIKit

UITableView

中有很多代理如果都換成

block

實作,會比

delegates

難好多。

2.一個委托對象的代理屬性隻能有個代理對象,如果想要委托對象調多個代理對象的回調應該用block。

3.單例對象最好不要

delegate

。單例對象由于始終都隻是同個對象,如果使

delegate

,就會造成

delegate

屬性被重新指派的問題,最終隻能有一個對象可以正常響應代法。

4.代理更加相過程,

block

則更面向結果。從設計模式的角度來說,代理更加面向過程,

block

更加向結果。

5.從性能上來說,

block

的性能消耗要略大于

delegate

,因為

block

會涉及到棧區向堆區拷等操作,時間和空間上的消耗都于代理。代隻是定義了個法清單,在遵守協定對象的

objc_protocol_list

中添加個節點,在運時向遵守協定的對象發送消息即可

題二:

Objective C

中多重繼承的實作機制。

什麼是多繼承?

假設C類要同時繼承A類和B類,則稱之為多繼承。這種情況就是多繼承。

oc中的“多繼承”

其實

Objective-C

不支援多繼承,由于消息機制名字查找發在運時非編譯時,很難解決多個基類可能導緻的義性問題。不過其實

Objective-C

也需持多繼承,我們可以找到如下種間接實作多繼承的方法:

  • 通過組合實作“多繼承”
  • 通過協定實作“多繼承”

通過協定實作“多繼承

雖然OC在文法上禁類使多繼承,但是卻可以協定來實作多繼承。協定隻能提供接,而沒有提供實作式,如果隻是想多繼承基類的接,那麼遵守多協定疑是最好的法。

此法缺點較明顯:需要修改兩個類,同時并不能調兩個類的原法,需要在類中實作法。

題三:簡述

Singleton

的概念及并使用

Objective C

寫出相關代碼。

Singleton: 單例模式。 簡單來說, 就是保證在你不主動銷毀這個單例對象的情況下, 整個項目中都始終擁有這個單例對象, 并且這個單例對象在記憶體中都是同一個記憶體位址。

是以, 單例很重要的兩個特點:

(1) app生命周期中一直存在(除主動銷毀外)

(2) 在整個生命周期中, 都是同一個記憶體位址

根據這兩個特點, 我來描述一個應用中的使用場景。 最簡單和常用的就是, 我們使用者的登入資訊, 不做本地緩存的話, 我們登入成功之後, 把伺服器請求下來的使用者資訊儲存到單例中。 比如這樣

[UserSingletonshareInstance].name = “張山”

。 接下來, 你無論在應用的任何頁面都可以直接通過[UserSingleton shareInstance].name的方式擷取到使用者的名字, 而且這個名字都是”張三”。 其他做法,都會比這個麻煩。

那麼怎麼寫單例呢? 核心的一點就是, 我們平時建立一個執行個體對象時候用到的方法(

alloc, init

), 都要重寫一遍,保證使用這些方法建立對象的時候是隻配置設定一塊記憶體位址,然後第一次建立之後再建立都指向前邊已經建立過得那個記憶體位址,順着這個思路,代碼如下:

然後,OC有個文法糖可以寫:

題四:簡述

@selector

的作用

Selector/SEL

又叫方法選擇器,

SEL在objc.h

中是這樣聲明的,而“

@selector()

”是取得一個

SEL

指針。說白了,方法選擇器僅僅是一個

char *

指針,表示它所代表的是方法的名字。 簡單來說: “

@Selector

就是用字元串表示某個類的某個方法。” 更加專業的說法是: “

Selector

就是OC的虛拟表(

virtual table

)中指向實際執行的函數指針(

function pointer

)的一個C字元。”

我們一般用它來“因為

method

可以用字元串表示,是以,某個

method

就可以變成用來傳遞的參數。” 再說的透明一點, 因為

selector

可以看做是函數的另一個名字,是以很多需要調用函數或者建立連接配接的地方,都可以用到,以下是一些具體的使用場景:

  • Target/Action

    模式
  • 檢查

    method

    是否存在
  • Timer

  • 線上程中執行方法
  • 數組排序
  • 代替

    if else / switch

  • 調用私有

    API

推薦 :

申請即送:

  • BAT大廠面試題、獨家面試工具包,
  • 資料免費領取,包括 資料結構、底層進階、圖形視覺、音視訊、架構設計、逆向安防、RxSwift、flutter,

繼續閱讀