第二季|高級(jí)進(jìn)階

1.KVC、KVO

2.runtime

3.block

4.GCD

5.RunLoop

1.Runloop是ios中一個(gè)非常重要的機(jī)制 ,ios系統(tǒng)底層很多模塊都通過Runloop機(jī)制來 實(shí)現(xiàn)的。例如界面更新,事件響應(yīng)等...

2.每條線程都有唯一對應(yīng)的Runloop對象,Runloop在第一次獲取時(shí)創(chuàng)建,在線程結(jié)束時(shí)銷毀.本質(zhì)就是EventLoop的do? while循環(huán)

3.ios系統(tǒng)提供了兩種Runloop:NSRunLoop和CFRunLoopRef. CFRunLoopRef是在CoreFoundation框架內(nèi)提供了C函數(shù)的API,這些API都是線程安全的. NSRunLoop是基于CFRunLoopRef的封裝,提供了面向?qū)ο蟮腁PI,不是線程安全的

4.CFRunLoopModeRef的運(yùn)行模式

kCFRunLoopDefaultMode:App的默認(rèn)運(yùn)行模式,通常主線程是在這個(gè)運(yùn)行模式下運(yùn)行

UITrackingRunLoopMode:跟蹤用戶交互事件(用于 ScrollView 追蹤觸摸滑動(dòng),保證界面滑動(dòng)時(shí)不受其他Mode影響)

UIInitializationRunLoopMode:在剛啟動(dòng)App時(shí)第進(jìn)入的第一個(gè) Mode,啟動(dòng)完成后就不再使用

GSEventReceiveRunLoopMode:接受系統(tǒng)內(nèi)部事件,通常用不到

kCFRunLoopCommonModes:偽模式,不是一種真正的運(yùn)行模式(后邊會(huì)用到)


5.RunLoop與Autoreleasepool

RunLoop寄生于線程,一個(gè)線程只能有唯一對應(yīng)的RunLoop,但可以嵌套子RunLoops.自動(dòng)釋放池寄生于RunLoop,程序啟動(dòng)后,主線程注冊了兩個(gè)Observer監(jiān)聽RunLoop的進(jìn)出與休眠。一個(gè)最高優(yōu)先級(jí)OB檢測Entry狀態(tài),一個(gè)最低優(yōu)先級(jí)OB監(jiān)聽BeforeWaiting狀態(tài)和Exit狀態(tài).

備注:運(yùn)行循環(huán)結(jié)束前會(huì)釋放自動(dòng)釋放池,還有池子滿了也會(huì)銷毀.

五、coreData

多線程處理大量數(shù)據(jù)同步時(shí)的操作

搭建coreData多線程環(huán)境

1.NSManagedObjectContext指定并發(fā)模式

2.NSConfinementConcurrencyType:向后兼容 IOS9后廢棄

3.NSPrivateQueueConcurrencyType:私有隊(duì)列中創(chuàng)建并管理Context

4.NSMainQueueCurrencyType:Context與UI相關(guān)用這種模式

大量數(shù)據(jù)處理

大量數(shù)據(jù)意味著需要我們關(guān)注內(nèi)存占用和性能,寫代碼時(shí)需要記得一下規(guī)劃:

1.盡可能緩存需要的數(shù)據(jù),不相關(guān)的數(shù)據(jù)保持faults狀態(tài)

2.fetch時(shí)盡可能精準(zhǔn),少引入不相關(guān)的數(shù)據(jù)

3.構(gòu)建多context時(shí)盡量將同類managed object集中,最大限度減少合并需求

4.提升操作效率,對asynchronous fetch, batch update,batch delete等新特性盡可能利用

CoreData是Cocoa處理數(shù)據(jù)綁定的方案之一,提供完整的對象持久化存儲(chǔ)方案.

CoreData與多線程交互的時(shí)候每個(gè)線程必須擁有一個(gè)ManagerContext

1.每個(gè)線程使用私有managerContext共享一個(gè)PersistentStoreCoordinator

2.每個(gè)線程使用私有managerContext和私有的PersistentStoreCoordinator

推薦使用第一種,第二種消耗過多內(nèi)存


?

六、線程鎖

鎖是常用的同步工具,一段代碼在同一時(shí)間只能被一個(gè)線程訪問

1.NSLock:互斥鎖 lock unlock trylock

2.@synchronized:代碼塊

3.dispatch-semaphore_t:信號(hào)量? 支持信號(hào)通知與信號(hào)等待,每發(fā)送一個(gè)信號(hào)通知,信號(hào)+1;每發(fā)送一個(gè)信號(hào)等待信號(hào)-1


七、weak

weak實(shí)現(xiàn)原理可概括為三步

1.初始化:runtime調(diào)用objc_initweak函數(shù),初始化一個(gè)新的weak指針指向?qū)ο蟮牡刂?

2.添加引用:objc_initweak函數(shù)會(huì)調(diào)用objc_storeWeak()函數(shù)從而更新指針指向,創(chuàng)建對應(yīng)弱引用表

3.釋放:調(diào)用clearDeallocating函數(shù).clearDeallocating函數(shù)首先根據(jù)對象地址獲取所有weak指針地址的數(shù)組,然后遍歷這些數(shù)組將其中數(shù)據(jù)置為nil.最后把這個(gè)entry從weak表中刪除,最后清理對象的記錄

從實(shí)現(xiàn)中可以看出,Weak指針的使用涉及到Hash表的增刪改查,存在一定的性能開銷.Weak指針盡量用Strong,倒不是擔(dān)心形成野指針,因?yàn)槟闶褂昧薟eak指針,對象就會(huì)被加入到autoreleasepool中,可以放心使用.是為了防止一次又一次加入autoreleasepool,存在性能開銷。


八、談?wù)勀銓ψ詣?dòng)釋放池的理解

1.自動(dòng)釋放池是OC提供的一種自動(dòng)回收機(jī)制,具有延時(shí)釋放的特性,即當(dāng)我們創(chuàng)建一個(gè)對象,并把它加入自動(dòng)釋放池中,不會(huì)立即釋放,會(huì)等到一次runloop結(jié)束或者作用域超出{}或者超出【pool release】之后再被釋放

2.Runloop寄生于線程:一個(gè)線程只能有唯一對應(yīng)的Runloop,可以嵌套子Runloops

3.自動(dòng)釋放池寄生于Runloop:程序啟動(dòng)后,主線程注冊了兩個(gè)Observer監(jiān)聽Runloop的進(jìn)出與睡覺。一個(gè)最高優(yōu)先級(jí)的OB監(jiān)聽Entry狀態(tài);一個(gè)最低優(yōu)先級(jí)的OB監(jiān)聽BeforeWaiting狀態(tài)和Exit狀態(tài)

線程(創(chuàng)建)--》runloop將進(jìn)入--》最高優(yōu)先級(jí)OB創(chuàng)建釋放池--》runloop將睡--》最低優(yōu)先級(jí)的OB銷毀舊線程池創(chuàng)建新池--》runloop將退出--》最低優(yōu)先級(jí)OB銷毀新池--》線程(銷毀)

4.默認(rèn)主線程運(yùn)行循環(huán)(runloop)是開啟的,子線程的運(yùn)行循環(huán)(runloop)默認(rèn)是不開啟的,也就意味著子線程不會(huì)創(chuàng)建autoreleasepool,所以需要我們自己在子線程中創(chuàng)建自動(dòng)釋放池。

7.自動(dòng)釋放池在mrc和arc的區(qū)別

自動(dòng)釋放池mac與arc

8.多層自動(dòng)釋放池嵌套的對象在哪一層釋放

最內(nèi)層釋放

9.對于block,理解,mrc和arc下有什么區(qū)別,使用注意事項(xiàng)

block的理解

1.MRC環(huán)境下,在定義block為屬性時(shí),使用copy的原因,是把block從棧區(qū)拷貝到堆區(qū),因?yàn)闂^(qū)中的變量出了作用域之后就會(huì)被銷毀,無法在全局使用,所以應(yīng)該把棧區(qū)的屬性拷貝到堆區(qū)中全局共享,這樣就不會(huì)被銷毀了,在MRC手動(dòng)管理的就是堆區(qū),不需要系統(tǒng)管理,MRC環(huán)境必須使用copy把變量拷貝到全局的堆區(qū)

2.如果是ARC的環(huán)境下,就可以不使用copy修飾,因?yàn)锳RC下的屬性本來就在堆區(qū)

3.很早的時(shí)候MRC的block屬性都是在棧區(qū)的,copy之后就到堆區(qū)了

4.當(dāng)前的ARC的block屬性默認(rèn)都在堆區(qū),使用copy知識(shí)沿襲了歷史的習(xí)慣,使用strong也是沒有問題的

__block修飾符

1.在block內(nèi)部,訪問外部的變量時(shí),內(nèi)部會(huì)對外部的變量進(jìn)行一次拷貝,在block內(nèi)部操作的是拷貝之后的副本,不會(huì)影響外部的變量,這個(gè)變量的堆區(qū)。

2.在block內(nèi)部,修改外部變量,是不被允許的,非要修改要用__block

3.一旦外部的int變量(在棧區(qū))被__block標(biāo)記了,如果block內(nèi)部修改了這個(gè)變量,那么這個(gè)變量的地址會(huì)永久的被修改在堆區(qū)

4.為什么在block內(nèi)部不能修改外部的變量?

因?yàn)閎lock一般是需要傳遞給另外一個(gè)類里面,block內(nèi)部的一些變量不能存儲(chǔ)在棧區(qū),需要存在堆區(qū),不然數(shù)據(jù)就容易丟失,這就是使用__block修飾的原因,這樣傳輸數(shù)據(jù)的時(shí)候,數(shù)據(jù)就不會(huì)丟失

5.weak原理


6.如果屬性完全不加修飾詞入weak,atomic,系統(tǒng)會(huì)怎么處理


七、線程間通信

八、數(shù)據(jù)庫如何實(shí)現(xiàn)讀寫分離

九、UITableview優(yōu)化

?

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

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

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,979評論 25 709
  • 不要聽信任何人的絕對判斷,他有不是上帝他怎么能知道結(jié)果呢,無非他做了只是沒有成功罷了,所以也只能告訴你這件事做不成...
    大牙牙53閱讀 139評論 0 0
  • 考研兄你好! 兄弟聽說你要考研,恭喜你做了你人生中第一個(gè)重大決定,不過作為經(jīng)歷過你人生中第一個(gè)轉(zhuǎn)折點(diǎn)的我想要給你說...
    Jachinzhao閱讀 407評論 2 6
  • 我所渴求的,無非是將心中脫穎而出的本性付諸生活。為什么竟如此艱難呢? 我并沒有以激烈的抗?fàn)幏绞礁鎰e父母和他們的世界...
    蕭言君閱讀 1,672評論 0 0
  • 50年前,我們還不知道互聯(lián)網(wǎng)是什么,20年前中國的互聯(lián)網(wǎng)才剛剛發(fā)芽,互聯(lián)網(wǎng)巨頭在當(dāng)年才剛剛成立,滿腔熱血的做著黃頁...
    獅子搞畫藝閱讀 248評論 0 0

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