隨手記

KeyChain

  • 數(shù)據(jù)并不是存放子App的沙盒中, 即使刪除了App, 數(shù)據(jù)依然保存在KeyChain中,如果重新安裝了App, 還可以從KeyChain中獲取數(shù)據(jù)
  • KeyChain的數(shù)據(jù)可以通過group方式, 讓程序可以在App間共享, 不過需要相同的TeamId
  • KeyChain的數(shù)據(jù)是經(jīng)過加密的

關(guān)于并行開發(fā)問題

首先在當(dāng)前主分支開出個(gè)人開發(fā)分支, 開發(fā)時(shí)要及時(shí)變基(rebase)以及合并個(gè)人分支至當(dāng)前主分支, 具體操作如下:

  • 當(dāng)日開發(fā)了的東西, 在當(dāng)前個(gè)人分支上點(diǎn)擊當(dāng)前主分支進(jìn)行變基操作
  • 變基完成, 切換到當(dāng)前主分支上, 合并當(dāng)前個(gè)人分支至當(dāng)前主分支

關(guān)于GCD

  • 同步執(zhí)行: 只能在當(dāng)前線程中執(zhí)行任務(wù), 不具備開啟新線程的能力(會(huì)立即執(zhí)行任務(wù), 會(huì)阻塞)
  • 異步執(zhí)行: 可以在新的線程中執(zhí)行任務(wù), 具備開啟新線程的能力(不會(huì)立即執(zhí)行任務(wù), 不會(huì)阻塞)
  • 并行隊(duì)列: 可以讓多個(gè)任務(wù)并行(同時(shí))執(zhí)行(自動(dòng)開啟多個(gè)線程同時(shí)執(zhí)行任務(wù))
  • 串行隊(duì)列: 讓任務(wù)一個(gè)接著一個(gè)地執(zhí)行(一個(gè)任務(wù)執(zhí)行完畢后, 才執(zhí)行下一個(gè)任務(wù))
  • 主隊(duì)列: GCD自帶的一種特殊的串行隊(duì)列
  • 所有放在主隊(duì)列中的任務(wù), 都是放到主線程中執(zhí)行
  • 可以使用dispatch_get_main_queue()獲取主隊(duì)列
  • 全局隊(duì)列: GCD自帶的一個(gè)并行的隊(duì)列

block和代理的區(qū)別

block比代理寫起來要方便很多, 但是block無法像代理那樣監(jiān)聽到狀態(tài)

autoreleasepool

自動(dòng)釋放池, 在MRC下, 調(diào)用[object autorelease]可以延遲對象的內(nèi)存釋放, 在ARC下, 又系統(tǒng)自動(dòng)幫助我們管理對象的內(nèi)存.

每一個(gè)線程都有一個(gè)NSAutoreleasePool棧, 當(dāng)一個(gè)新的池子被創(chuàng)建的時(shí)候, push進(jìn)棧. 當(dāng)池子被釋放內(nèi)存時(shí), pop出棧, 對象調(diào)用autorelease方法進(jìn)入棧頂?shù)某刈又? 當(dāng)線程結(jié)束的時(shí)候, 它會(huì)自動(dòng)銷毀所有跟它相關(guān)聯(lián)的池子.

autorelease pool 與RunLoop

程序運(yùn)行->開啟事件循環(huán)->發(fā)生觸摸事件->創(chuàng)建自動(dòng)釋放吃->處理觸摸事件->事件對象自動(dòng)加入自動(dòng)釋放池->一次事件循環(huán)結(jié)束, 銷毀自動(dòng)釋放池

什么時(shí)候需要自己手動(dòng)創(chuàng)建autoreleasepool?

  1. 你寫的程序不是基于UI framework的, 例如命令行項(xiàng)目.
  2. 你寫的循環(huán)創(chuàng)建了大量臨時(shí)對象 -> 你需要在循環(huán)體內(nèi)創(chuàng)建一個(gè)autorelease pool block, 并且每次循環(huán)結(jié)束之前處理那些autoreleased對象, 在循環(huán)中使用autorelease pool block可以降低內(nèi)存峰值.
  3. 你創(chuàng)建了一個(gè)新線程, 當(dāng)線程開始執(zhí)行的時(shí)候你必須立馬創(chuàng)建一個(gè)autorelease pool block, 否則你的應(yīng)用會(huì)造成內(nèi)存泄漏

使用場景:

  1. 利用@autoreleasepool優(yōu)化循環(huán)
  2. 如果你的應(yīng)用程序或者線程是要長期運(yùn)行的并且有可能產(chǎn)生大量autoreleased對象, 應(yīng)該使用autorelease pool blocks
  3. 長期在后臺(tái)中運(yùn)行的任務(wù), 方法

性能優(yōu)化

  • 使用ARC管理內(nèi)存
  • 避免使用sb, xib
  • 懶加載控件
  • 緩存數(shù)據(jù)
  • 避免離屏渲染(圓角的使用會(huì)導(dǎo)致離屏渲染, 混合圖層可以避免)
  • 優(yōu)化TableView

啟動(dòng)優(yōu)化

啟動(dòng)時(shí)間的分布:

Total pre-main time: 652.06 milliseconds (100.0%)
         dylib loading time: 148.18 milliseconds (22.7%)
        rebase/binding time: 427.07 milliseconds (65.4%)
            ObjC setup time:  41.64 milliseconds (6.3%)
           initializer time:  34.94 milliseconds (5.3%)
           slowest intializers :
               libSystem.dylib :   2.32 milliseconds (0.3%)
    libMainThreadChecker.dylib :  21.60 milliseconds (3.3%)

根據(jù)啟動(dòng)時(shí)間的輸出日志可以從四個(gè)階段入手:

  • 對動(dòng)態(tài)庫加載的時(shí)間優(yōu)化. 減少動(dòng)態(tài)庫集成或者盡可能地將多個(gè)動(dòng)態(tài)庫集成一個(gè)動(dòng)態(tài)庫后進(jìn)行導(dǎo)入, 盡量保證將App現(xiàn)有的非系統(tǒng)級的動(dòng)態(tài)庫個(gè)數(shù)保證在6個(gè)以內(nèi).
  • 減少App的類, 分類和唯一Selector的個(gè)數(shù), 這樣做主要是為了加快程序的整個(gè)動(dòng)態(tài)鏈接, 在進(jìn)行動(dòng)態(tài)庫的重定位和綁定(Rebase/binding)過程中減少指針修改的使用, 加快程序機(jī)器碼的生成.
  • 使用initialize方法進(jìn)行必要的初始化工作, 不在+load方法中執(zhí)行初始化工作, 原因是+load會(huì)在App第一次啟動(dòng)的過程中加載, 而initialize方法是在第一次使用到這個(gè)類的時(shí)候才會(huì)加載. 能夠有效加快所有類文件的加載速度

Runtime實(shí)現(xiàn)weak屬性

runtime對注冊的類, 會(huì)進(jìn)行布局, 對于weak對象會(huì)放入一個(gè)hash表中, 用weak指向的對象內(nèi)存地址作為key, 當(dāng)此對象的引用計(jì)數(shù)為0的時(shí)候回調(diào)用dealloc方法,
此時(shí)就會(huì)以被weak修改的對象的內(nèi)存地址作為key, 在這個(gè)hash表中搜索, 找到所有以這個(gè)key的對象, 設(shè)置為nil.

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

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

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