iOS知識點(diǎn)匯總

UI試圖

UITableView相關(guān)

1.cell的復(fù)用
2.數(shù)據(jù)源同步:

  • 并發(fā)訪問、數(shù)據(jù)拷貝(缺點(diǎn):拷貝數(shù)據(jù)產(chǎn)生內(nèi)存開銷)


    image.png
  • 串行訪問 (缺點(diǎn):子線程操作耗時時,刪除會有延遲)


    image.png
事件傳遞&視圖響應(yīng)

UIView提供內(nèi)容,以及負(fù)責(zé)處理觸摸等事件,參與響應(yīng)鏈
CALayer負(fù)責(zé)顯示內(nèi)容的contents

  • 事件傳遞:
    主要方法
    -(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
    -(BOOL)pointInside(CGPoint)point withEvent:(UIEvent *)event
    流程


    image.png
  • 響應(yīng)鏈:
    主要方法
    -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
    -(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
    -(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
    流程


    image.png
圖像顯示原理

CPU和GPU是通過總線連接起來的,CPU輸出的是位圖,再經(jīng)由總線在合適的時機(jī)上傳給GPU,GPU拿到位圖后會做圖層的渲染、紋理的合成,之后把結(jié)果放到幀緩沖區(qū)中,由視頻控制器根據(jù)VSync信號在指定時間之前去提取幀緩沖中的屏幕顯示內(nèi)容,最終顯示到屏幕上。


image.png

image.png
  • CPU工作
    Layout UI布局、文本計(jì)算
    Display 繪制
    Prepare 圖片編解碼
    Commit 提交位圖
  • GPU渲染管線
    頂點(diǎn)著色
    圖元裝配
    光柵化
    片段著色
    片段處理
UI卡頓、掉幀

原因:1s完成60幀的刷新,在視覺上是流暢的,也就是每個VSync之間有16.7ms,在這16.7ms之間,要CPU和GPU共同完成下一幀畫面的合成,不能完成則會導(dǎo)致卡頓(掉幀)


image.png

界面滑動優(yōu)化方案:

  • CPU
    對象的創(chuàng)建、調(diào)整、銷毀放到子線程中操作
    預(yù)排版(布局計(jì)算、文本計(jì)算)
    預(yù)渲染(文本等異步繪制,圖片編解碼等)
  • GPU
    紋理渲染(給layer設(shè)置圓角、陰影等會觸發(fā)離屏渲染)
    視圖混合(減少層級)
UI繪制原理/異步繪制

調(diào)用UIView的setNeedsDisplay方法,并不會立刻發(fā)生當(dāng)前視圖的繪制工作,而是先調(diào)用layer的setNeedDisplay方法,相當(dāng)于在當(dāng)前l(fā)ayer上打上一個臟標(biāo)記,然后在當(dāng)前RunLoop將要結(jié)束前調(diào)用CALayer的display方法,去繪制試圖


繪制原理.png

異步繪制:
layer.delegate實(shí)現(xiàn)了displayLayer:方法,進(jìn)入異步繪制流程中

  • 代理負(fù)責(zé)生成對應(yīng)的bitmap
  • 設(shè)置該bitmap作為layer.contents屬性的值


    異步繪制.png
離屏渲染

在屏渲染:GPU的渲染操作是在當(dāng)前用于顯示的屏幕緩沖區(qū)中進(jìn)行的
離屏渲染:GPU在當(dāng)前屏幕緩沖區(qū)以外新開辟一個緩沖區(qū)進(jìn)行渲染操作。當(dāng)我們設(shè)置UI視圖的圖層屬性時(圓角,遮罩,陰影),如果指定為在未預(yù)合之前(無法把渲染結(jié)果直接寫入幀緩存區(qū),而是暫存在另外的內(nèi)存區(qū)域之后再寫入frame buffer)不能用于直接顯示的時候,就會觸發(fā)離屏渲染。
為何要避免:會創(chuàng)建新的渲染緩沖區(qū),GPU會產(chǎn)生額外的開銷,很有可能導(dǎo)致CPU和GPU繪制一幀的時間超過16.7ms,會造成卡頓和掉幀

OC語言

分類Category
  • 特點(diǎn):
    1.運(yùn)行時決議(運(yùn)行時通過Runtime把分類中添加的內(nèi)容添加到原類中)
    2.可以為系統(tǒng)類添加分類

  • 可以添加哪些內(nèi)容
    實(shí)例方法、類方法、協(xié)議、屬性

  • 結(jié)構(gòu)體


    分類結(jié)構(gòu)體.png
  • 程序啟動加載調(diào)用棧(image為鏡像)
    _objc_init(runtime初始化)
    map_2_images(程序鏡像的處理)
    map_images_nolock
    _read_images(加載可執(zhí)行文件到內(nèi)存中)
    remethodizeClass(分類加載內(nèi)容在此)

  • 原理
    倒敘遍歷原類的所有分類(最先訪問最后編譯的分類),把實(shí)例方法、類方法、協(xié)議、屬性放入不同的二維數(shù)組中,獲取原類當(dāng)中的rw數(shù)據(jù),其中包含原類的方法列表信息,根據(jù)拼接之后的元素總數(shù)重新分配內(nèi)存,通過memmove把原類方法進(jìn)行內(nèi)存移動,移動到最后面,memcopy把分類中的方法copy到原類的內(nèi)存中。所以原類的方法還存在,只是調(diào)用順序問題。

關(guān)聯(lián)對象

可以為分類添加實(shí)例變量
objc_getAssociatedObject(id object, const void *key)
objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy)
objc_removeAssociatedObjects(id object)

  • 本質(zhì)
    關(guān)聯(lián)對象由AssociationsManager管理并在AssociationsHashMap中存儲。
    所有對象的關(guān)聯(lián)內(nèi)容都在同一個全局容器中。
    @selector(text)-key COPY/RETAIN-Policy


    image.png
擴(kuò)展

擴(kuò)展Extension

  • 格式
@interface XXX ()
//私有屬性
//私有方法(如果不實(shí)現(xiàn),編譯時會報(bào)警,Method definition for 'XXX' not found)
@end
  • 使用
    聲明私有屬性
    聲明私有方法
    聲明私有成員變量
  • 特點(diǎn)
    編譯時決議
    只以聲明的形式存在,多數(shù)情況下寄生于宿主類的.m中
    不能為系統(tǒng)類添加擴(kuò)展
代理

是一種軟件設(shè)計(jì)模式
傳遞方式是一對一的

NSNotification
  • 特點(diǎn)
    是使用觀察者設(shè)計(jì)模式來實(shí)現(xiàn)的用于跨層傳遞消息的機(jī)制
    傳遞方式是一對多的
  • 如何實(shí)現(xiàn)通知機(jī)制
    NSNotificationCenter內(nèi)部會維護(hù)一個Notification_Map表, notificationName為key,Observers_List為value


    image.png
KVO
  • KVO:key-value observing
    是OC對觀察者設(shè)計(jì)模式的又一實(shí)現(xiàn)
    Apple使用了isa混寫(isa-swizzling)來實(shí)現(xiàn)KVO
  • isa-swizzling
    A在運(yùn)行時會動態(tài)生成一個NSKVONotifying_A類(A的子類),然后將A類的實(shí)例對象的isa指針指向NSKVONotifying_A類,
    觀察A的name屬性:
    1、重寫set方法,并在設(shè)置操作的前后分別調(diào)用 willChangeValueForKey: 和 didChangeValueForKey方法,這兩個方法用于通知系統(tǒng)該 key 的屬性值即將和已經(jīng)變更了
    2、重寫class方法,返回原來的A類對象
    3、重寫dealloc方法,再合適的時候銷毀這個運(yùn)行時創(chuàng)建的類


    image.png
  • 通過kvc設(shè)置name kvo能否生效
    可以。和kvc的實(shí)現(xiàn)有關(guān)
  • 通過成員變量直接賦值name kvo是否生效
    不能,直接賦值不會走set方法,可以在賦值前后加上willChangeValueForKey: 和 didChangeValueForKey
KVC

如果沒有找到Set方法的話,會先根據(jù)accessInstanceVariablesDirectly返回實(shí)例變量是否存在,YES會按照_key,_iskey,key,iskey的順序搜索成員并進(jìn)行賦值操作,都沒有會調(diào)用valueForUndefinedKey:

屬性關(guān)鍵字
  • 讀寫權(quán)限
    readonly
    readwrite(系統(tǒng)默認(rèn))
  • 原子性
    1.atomic(系統(tǒng)默認(rèn)):可以保證賦值和獲取是線程安全的,并不代表操作(如:數(shù)組的增加和移除)和訪問
    2.nonatomic
  • 引用計(jì)數(shù)
    retain(MAC)/strong(ARC)
    assign(基本數(shù)據(jù)類型、對象類型)/unsafe_assign(MRC中使用頻繁)
    weak/copy
    1、assign和weak的區(qū)別:
    assign:修飾基本數(shù)據(jù)類型;修飾對象時,不改變其引用計(jì)數(shù);會產(chǎn)生野指針。
    weak:不改變被修飾對象的引用計(jì)數(shù);所指對象在被釋放后會自動置為nil。
    2、copy和mutableCopy/深拷貝和淺拷貝

Runtime

對象、類對象、元類對象

對象,指向類對象
類對象,指向元類對象

  • 整體數(shù)據(jù)結(jié)構(gòu)


    數(shù)據(jù)結(jié)構(gòu).png

    image.png
  • 類對象(objc_class類型數(shù)據(jù)結(jié)構(gòu))
    存儲實(shí)例方法列表等信息

  • 元類對象(objc_class類型數(shù)據(jù)結(jié)構(gòu))
    存儲類方法列表等信息,元類對象的isa指針都指向根元類,根元類對象的isa指針也指向根元類。根元類對象的superClass指針指向根類對象

  • 如果類方法沒有實(shí)現(xiàn),在根類對象里面有同名實(shí)例方法,才能調(diào)用

消息傳遞機(jī)制
消息傳遞.png
  • 緩存查找
    根據(jù)給定的方法選擇器SEL,找到對應(yīng)的方法實(shí)現(xiàn)(通過哈希查找找到對應(yīng)的bucket_t)


    image.png
  • 當(dāng)前類中查找
    對于已排序好的方法列表。采用二分查找算法查找方法對應(yīng)執(zhí)行函數(shù)
    對于沒有排序的方法列表,采用一般遍歷查找
  • 父類逐級查找


    image.png
消息轉(zhuǎn)發(fā)流程
  • resolveInstanceMethod:/resolveClassMethod:
  • forwadingTargetForSelector:
  • methodSignatureForSelector:
    forwardInvocation:
Method-Swizzling
  • method_exchangeImplementations()
動態(tài)添加方法
class_addMethod(Class cls, SEL name, IMP imp, const char * types)

內(nèi)存管理

內(nèi)存布局

stack:方法調(diào)用
heap:通過alloc等分配的對象

  • 內(nèi)存管理方案
    1、TaggedPointer (一些小對象,如NSNumber)
    2、NONPOINTER_ISA (64位架構(gòu)下的ios應(yīng)用程序。在64位架構(gòu)下,isa指針占64個比特位,但只需要32位就夠了,為了提高內(nèi)存利用率,在剩余的比特位中存儲了一些關(guān)于內(nèi)存管理的數(shù)據(jù)內(nèi)容)
    3、散列表 (SideTables,引用計(jì)數(shù)、弱引用表)


    SideTable結(jié)構(gòu)
ARC

自動引用計(jì)數(shù)管理內(nèi)存
ARC是編譯器(自動插入retain、release)和Runtime共同協(xié)作
ARC中禁止手動調(diào)用retain/release/retainCount/dealloc(ARC下可以重寫dealloc方法,但是不能顯示調(diào)用super dealloc)
新增weak、strong屬性關(guān)鍵字

MRC

手動引用計(jì)數(shù)(斜體方法在ARC中調(diào)用會編譯報(bào)錯)
alloc:分配對象的內(nèi)存空間
retain:引用計(jì)數(shù)+1
release:引用計(jì)數(shù)-1
retainCount:當(dāng)前對象的引用計(jì)數(shù)值
autorelease:autoreleasePool結(jié)束時調(diào)用release
dealloc:顯示調(diào)用[super dealloc]

引用計(jì)數(shù)機(jī)制
  • alloc實(shí)現(xiàn)
    經(jīng)過一系列調(diào)用,最終調(diào)用C函數(shù)的calloc
    此時并沒有設(shè)置引用計(jì)數(shù)為1。(調(diào)用retainCount返回1,和retainCount的實(shí)現(xiàn)有關(guān))
  • retain實(shí)現(xiàn)
//通過哈希查找對象引用計(jì)數(shù)相關(guān)的sidetable,從sidetables中找到sidetable
SideTable& table = SidTables()[this];
//獲取引用計(jì)數(shù)map,通過哈希查找從中獲取引用計(jì)數(shù)值
size_t& refcntStorage = table.refcnts[this];
//引用計(jì)數(shù)+1,實(shí)際是加偏移量4,反應(yīng)出的結(jié)果是+1
refcntStorage += SIDE_TABLE_RC_ONE;
  • release實(shí)現(xiàn)
SideTable& table = SidTables()[this];
RefcountMap::iterator it = table.refcnts.find(this);
//引用計(jì)數(shù)-1
it->sencond -= SIDE_TABLE_RC_ONE;
  • retainCount
SideTable& table = SidTables()[this];
size_t refcnt_result = 1;
RefcountMap::iterator it = table.refcnts.find(this);
//alloc沒有給對象進(jìn)行+1,由于refcnt_result為1,所以調(diào)用retainCount為1
refcnt_result += it->second >> SIDE_TABLE_RC_SHIFT;
  • dealloc


    image.png
弱引用表
  • 添加weak變量
    在weak_register_no_lock()函數(shù)中進(jìn)行弱引用變量的添加,通過哈希算法進(jìn)行位置查找,如果查找到的位置中已經(jīng)有對應(yīng)的弱引用數(shù)組,把弱引用指針添加到數(shù)組中,如果沒有會創(chuàng)建弱引用數(shù)組,第0個位置上添加最新的weak指針,后面都初始化為nil
objc_initWeak() -> storeWeak() -> weak_register_no_lock()
  • 清除weak變量,同時設(shè)置指向nil
    weak_clear_no_lock()根據(jù)當(dāng)前對象指針查找弱引用表,遍歷當(dāng)前對象的弱引用數(shù)組,把弱引用指針置為nil
dealloc() -> clearDeallocating() -> weak_clear_no_lock()
AutoReleasePool

編譯器會將@autorealsepool{}改為

void *ctx = objc_autoreleasePoolPush(); (-> AutoreleasePoolPage::push)
{}代碼塊
//一次pop相當(dāng)于一次批量的pop操作
objc_autoreleasePoolPop(ctx);(-> AutoreleasePoolPage::pop)
  • 結(jié)構(gòu)
    是以棧為結(jié)點(diǎn),通過雙向鏈表的形式組合而成的數(shù)據(jù)結(jié)構(gòu)(雙向鏈表:每個結(jié)點(diǎn)都有兩個指針,ParentPtr、ChildPtr)
    和線程是一一對應(yīng)的
  • AutoreleasePoolPage
    id* next;
    AutoreleasePoolPage* const parent;
    AutoreleasePoolPage* child;
    pthread_t const thread;
  • 自動釋放池
    在當(dāng)次runloop將要結(jié)束的時候調(diào)用AutoreleasePoolPage::pop()
    多層嵌套就是多次插入哨兵對象
    在for循環(huán)中alloc圖片數(shù)據(jù)等內(nèi)存消耗較大的場景手動插入autoreleasePool(每次循環(huán)都會完成一次內(nèi)存的釋放)
循環(huán)引用

自循環(huán)引用
相互循環(huán)引用
多循環(huán)引用

  • 破除循環(huán)引用
    避免產(chǎn)生循環(huán)應(yīng)用;在合適的時機(jī)手動斷環(huán)
    (__weak;
    __block—在MRC下,__block修飾對象不會增加其引用計(jì)數(shù),避免了循環(huán)引用;在ARC下,__block修飾對象會被強(qiáng)引用,無法避免循環(huán)引用,需手動解環(huán);
    __unsafe_unretained—和__weak等效,但是被修飾的對象被釋放后會產(chǎn)生野指針問題)
  • NSTimer循環(huán)引用問題
    調(diào)用invalidate,從runloop中移除,設(shè)為nil 釋放對target對象的強(qiáng)引用
    不直接持有,引入中間對象持有兩個弱引用,NSTimer和原對象

Block

Block本質(zhì)-對象

Block是將函數(shù)及其執(zhí)行上下文封裝起來的對象

截獲變量特性
  • 局部變量
    基本數(shù)據(jù)類型:截獲其值
    對象類型:連同所有權(quán)修飾符一起截獲(和循環(huán)引用有關(guān)聯(lián))
  • 靜態(tài)局部變量:指針形式
  • 全局變量:不截獲
  • 靜態(tài)全局變量:不截獲
__block修飾符的本質(zhì)

一般情況下,對被截獲變量進(jìn)行賦值操作需要添加__block修飾符(賦值 != 操作)
__block修飾的變量變成了對象

__block int xxx;
struct _Block_byref_XXX_0 {
    void *isa;
    //棧上的__forwarding指針指向自身
    //棧上的block進(jìn)行copy操作后,棧上的__forwarding指向堆上的block,堆上的__forwarding     指向自身
    _Block_byref_XXX_0 *__forwarding;  
    int __flags;
    int __size;
    int XXX;
}
Block的內(nèi)存管理

GlobalBlock(放在已初始化數(shù)據(jù)區(qū)中)
StackBlock(被銷毀時,__block修飾的對象和block都會被銷毀)
MallocBlock(堆上的block)

  • Block的copy操作


    image.png
循環(huán)引用

__weak修飾

多線程

GCD
  • 同步/異步 和 串行/并發(fā)
    死鎖:隊(duì)列引起的循環(huán)等待
  • dispatch_barrier_async
    解決多讀單寫的問題
  • dispatch_group
NSOperation/NSOperationQueue
  • 添加/移除任務(wù)依賴
  • 任務(wù)執(zhí)行狀態(tài)的控制
    isReady
    isExecuting
    isFinished(是通過KVO機(jī)制實(shí)現(xiàn)的)
    isCancelled
    如果只重寫了main方法,底層控制變更任務(wù)執(zhí)行完成狀態(tài),以及任務(wù)退出
    如果重寫了start方法,自行控制任務(wù)狀態(tài)
  • 最大并發(fā)量
NSThread
  • 啟動流程
start() -> 創(chuàng)建pthread -> main() -> [target performSelector:selector] -> exit()
  • 結(jié)合RunLoop實(shí)現(xiàn)常駐線程
互斥鎖、自旋鎖、遞歸鎖等
  • @synchronized
    一般在創(chuàng)建單例對象的時候使用
  • atomic
    修飾屬性的關(guān)鍵字;
    對被修飾對象進(jìn)行原子操作(不負(fù)責(zé)使用,對mutableArr.addObject操作不能保證線程安全)
  • OSSpinLock
    自旋鎖;循環(huán)等待詢問,并不釋放當(dāng)前資源
    用于輕量級數(shù)據(jù)訪問,簡單的int值+1/-1操作
  • NSLock
    獲取到鎖,再獲取會導(dǎo)致死鎖(可使用遞歸鎖進(jìn)行解決)


    image.png
  • NSRecursiveLock
    遞歸鎖;可以重入


    image.png
  • dispatch_semaphore_t
    信號量
  • dispatch_semaphore_create(0);
struct semaphore {
  int value;
  List <thread>;
}
  • dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
{
  S.value = S.value - 1;
  //阻塞是一個主動行為
  if S.value < 0 then Block(S.List)
}
  • dispatch_semaphore_signal(semaphore); //發(fā)送信號量
{
  S.value = S.value + 1;
  //喚醒是一個被動行為
  if S.value >= 0 then wakeup(S.List);
}

RunLoop

什么是RunLoop

RunLoop是通過內(nèi)部維護(hù)的事件循環(huán)來對事件/消息進(jìn)行管理的一個對象
沒有消息處理時,休眠以避免資源占用(用戶態(tài),通過系統(tǒng)調(diào)用進(jìn)入內(nèi)核態(tài))
有消息處理時,立刻被喚醒(內(nèi)核態(tài) -> 用戶態(tài))
不是個簡單的while循環(huán),主要是發(fā)生了狀態(tài)切換

數(shù)據(jù)結(jié)構(gòu)

NSRunLoop是對CFRunLoop的封裝,提供了面向?qū)ο蟮腁PI

  • CFRunLoop
struct __CFRunLoop {    
    pthread_t _pthread;  //對應(yīng)的線程  RunLoop和線程一一對應(yīng)
    CFMutableSetRef _commonModes; //多個commonModes <String>
    CFMutableSetRef _commonModeItems;   //多個Observer,多個Timer,多個Source
    CFRunLoopModeRef _currentMode;  //當(dāng)前運(yùn)行的mode
    CFMutableSetRef _modes; //多個modes <CFRunLoopMode>
};
  • CFRunLoopMode
struct __CFRunLoopMode {
    CFMutableSetRef _sources0;  //需要手動喚醒當(dāng)前線程
    CFMutableSetRef _sources1;  //具備喚醒線程的能力
    CFMutableArrayRef _observers;   //
    CFMutableArrayRef _timers;   //
};
  • Source/Timer/Observer
    CFRunLoopObserverRef監(jiān)聽runloop的狀態(tài)
各數(shù)據(jù)結(jié)構(gòu)間的關(guān)系
事件循環(huán)機(jī)制

有事做事,沒事做時休息


image.png
RunLoop和NSTimer

用戶滑動ScrollView時,RunLoop會轉(zhuǎn)到UITrackingRunLoopMode,Mode發(fā)生切換,timer不會再生效了

  • 解決方案
    通過CFRunLoopAddTimer(CFRunLoopRef rl, CFRunLoopTimerRef timer, CFRunLoopMode mode )方法將timer添加到NSRunLoopCommonModes中
RunLoop與線程之間的關(guān)系

線程與RunLoop是一一對應(yīng)的
自己創(chuàng)建的線程默認(rèn)是沒有RunLoop的

常駐線程

1、為當(dāng)前線程開啟一個RunLoop
2、向該RunLoop中添加一個Port/Source等維持RunLoop的時間循環(huán)
3、啟動該RunLoop

保證子線程數(shù)據(jù)回來更新UI的時候不打斷用戶的滑動操作

可以把更新UI放到DefaultMode下,這樣不會在TrackingMode下更新UI

網(wǎng)絡(luò)

HTTP協(xié)議

超文本傳輸協(xié)議

  • 請求/響應(yīng)報(bào)文
  • 連接建立流程
  • HTTP特點(diǎn)
HTTPS與網(wǎng)絡(luò)安全
TCP/UDP
DNS解析

域名到IP地址的映射,DNS解析請求采用UDP數(shù)據(jù)報(bào),且明文

  • 遞歸查詢
    我去給你問一下


    image.png
  • 迭代查詢
    我告訴你誰可能知道


    image.png
  • DNS解析中常見的問題
    1、DNS劫持問題


    image.png

    2、DNS解析轉(zhuǎn)發(fā)問題

  • DNS劫持怎么解決
    1、httpDNS:
    使用DNS協(xié)議向DNS服務(wù)器的53端口進(jìn)行請求(也就是使用HTTP協(xié)議向服務(wù)器的80端口進(jìn)行請求,通過ip像服務(wù)端進(jìn)行請求,返回給域名的ip地址)
    2、長連接


    image.png
Session/Cookie

對HTTP協(xié)議無狀態(tài)特點(diǎn)的補(bǔ)償
Cookie:保存在客戶端,用來記錄用戶狀態(tài)

設(shè)計(jì)模式

六大設(shè)計(jì)原則
  • 單一職責(zé)原則
    一個類只負(fù)責(zé)一件事(UIView和CALayer)
  • 依賴倒置原則
    抽象不應(yīng)該依賴具體實(shí)現(xiàn),具體實(shí)現(xiàn)可以依賴于抽象(上層業(yè)務(wù)只依賴于提供的接口,并不關(guān)心內(nèi)部實(shí)現(xiàn))
  • 開閉原則
    對修改關(guān)閉,對擴(kuò)展開放
  • 里氏替換原則
    父類可以被子類無縫替換,且原有功能不受影響(KVO)
  • 接口隔離原則
    使用多個專門的協(xié)議,而不是一個龐大臃腫的協(xié)議(UITableViewDelegate和UITableViewDataSource)
    協(xié)議中的方法應(yīng)該盡量少
  • 迪米特法則
    一個對象對其他對象有盡可能少的了解,高內(nèi)聚低耦合
責(zé)任鏈

實(shí)際需求:對于業(yè)務(wù)A -> 業(yè)務(wù)B -> 業(yè)務(wù)C 變更為 業(yè)務(wù)C -> 業(yè)務(wù)B -> 業(yè)務(wù)A
業(yè)務(wù)C的nextBusinessObject為業(yè)務(wù)B,業(yè)務(wù)B的nextBusinessObject為業(yè)務(wù)C


類構(gòu)成
橋接
適配器
單例
命令

架構(gòu)/框架

模塊化
分層
解耦
降低代碼重合度

圖片緩存框架
image.png
  • 圖片讀寫
    以圖片URL的單向Hash值作為key
    內(nèi)存方面淘汰策略:
    1、隊(duì)列先進(jìn)先出
    2、LRU算法,如30分鐘內(nèi)未使用過(觸發(fā)時機(jī)每次進(jìn)行圖片查找時,后臺切換到前臺時)
    磁盤設(shè)計(jì):
    1、存儲方式
    2、大小限制
    3、淘汰策略(7天以上的刪除)
    網(wǎng)絡(luò)設(shè)計(jì):
    1、圖片請求的最大并發(fā)量
    2、請求的超時策略(超時重試)
    3、請求優(yōu)先級
    圖片解碼:
    1、應(yīng)用策略模式對不同圖片格式進(jìn)行解碼
閱讀時長統(tǒng)計(jì)框架
image.png
復(fù)雜頁面架構(gòu)
  • MVVM框架思想

  • ReactNative的數(shù)據(jù)流思想
    任何一個子節(jié)點(diǎn)是沒有權(quán)利做自己的變化更新的(打一個標(biāo)記),必須把自己變化更新的消息傳遞給根結(jié)點(diǎn),由根結(jié)點(diǎn)自頂向下的方式詢問哪些結(jié)點(diǎn)需要更新


    RN數(shù)據(jù)流思想
  • 系統(tǒng)UIView更新機(jī)制的思想

  • FaceBook的開源框架AsyncDisplayKit關(guān)于預(yù)排班的設(shè)計(jì)思想

客戶端整體架構(gòu)
image.png
  • 業(yè)務(wù)之間的解耦通信方式
    OpenURL
    依賴注入(通過中間層解耦)

算法

字符串反轉(zhuǎn)
鏈表反轉(zhuǎn)
有序數(shù)組合并
Hash算法
查找兩個子視圖的共同父試圖
求無序數(shù)組當(dāng)中的中位數(shù)

三方庫

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

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

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