簡單記錄下理解的iOS知識點

一.在查看優(yōu)化經(jīng)驗文章的時候欣簇,經(jīng)常會看到關(guān)于+loadinitialize兩個方法巾钉,其中+load方法翘狱,是只要程序啟動了,程序就會將所有代碼加載到內(nèi)存的代碼區(qū)砰苍,此時潦匈,這個+load方法就會執(zhí)行,同時赚导,此方法會在main函數(shù)執(zhí)行前就調(diào)用茬缩,而 initialize是該類初始化時候才調(diào)用。所以推薦在做啟動優(yōu)化的時候吼旧,要檢查系統(tǒng)中的無用類凰锡、過期類,合并多余類圈暗、中間類掂为,因為每次啟動app,這些都會加載一遍员串。

二.啟動時間大體可分為兩步(冷啟動熱啟動就算了勇哗,不區(qū)分了):
第一步:main函數(shù)加載之前,系統(tǒng)會加載動態(tài)庫寸齐、引入類的+load方法等欲诺,所以需要:刪減不必要的動態(tài)庫,定期檢查系統(tǒng)中無用類渺鹦,過期類扰法,合并多余中間類(多說一嘴,中小項目沒必要用MVVM)海铆,除了系統(tǒng)動態(tài)庫迹恐,個人創(chuàng)建的動態(tài)庫多常見于一些自己封裝的UIKit,可以考慮封裝成靜態(tài)庫卧斟,或者合并殴边。
第二步:main函數(shù)加載之后,此時珍语,主要是針對業(yè)務(wù)模塊進行優(yōu)化锤岸,
1.日志、統(tǒng)計板乙、廣告業(yè)等必須一開始加載的功能是偷,保留在didFinishLaunchingWithOptions中拳氢。
2.推送、項目配置蛋铆、環(huán)境配置馋评、信息初始化等必須在主頁面進入前完成的工作,放到廣告頁的viewDidAppear里進行刺啦。
3.其他SDK和配置事件留特,由于啟動時間不是必須的,所以可以放到首頁的viewDidAppear里進行玛瘸。
4.初始化tabbar的時候蜕青,除了首頁外,延遲其他幾個控制器的創(chuàng)建時間糊渊,比如“個人中心”右核,“訂單”等模塊,用空的viewController占位渺绒,第一次點擊的時候再初始化加載贺喝。

其他更厲害的優(yōu)化,可以參考抖音團隊分享的:基于二進制文件重排的解決方案芒篷。http://www.zyiz.net/tech/detail-127196.html

三:KVO是如何實現(xiàn)監(jiān)聽的
KVO底層使用了 isa-swizling的技術(shù).
OC中每個對象/類都有isa指針, isa 表示這個對象是哪個類的對象.
當(dāng)使用KVO給對象的某個屬性注冊了一個 observer搜变,系統(tǒng)會創(chuàng)建一個新的中間類(intermediate class)繼承原來的class,把該對象的isa指針指向中間類(這樣针炉,這個對象的類其實就改變?yōu)檫@個新創(chuàng)建的中間類)。
然后中間類會重寫該屬性的setter方法扳抽,當(dāng)這個屬性的值更改的時候篡帕,會在調(diào)用setter之前調(diào)用willChangeValueForKey, 調(diào)用setter之后調(diào)用didChangeValueForKey,以此通知所有觀察者值發(fā)生更改贸呢。
之后重寫了 -class 方法镰烧,企圖欺騙我們這個類沒有變,就是原本那個類楞陷。

四:NSTimer的循環(huán)引用和Block循環(huán)引用有什么區(qū)別怔鳖?
__weak typeof(self) weakSelf = self;
self.timer = [NSTimer timerWithTimeInterval:1 target:weakSelf selector:@selector(timerAction) userInfo:nil repeats:YES];
同樣是用__weak修飾self,為什么NSTimer會導(dǎo)致循環(huán)引用固蛾,而block不會呢结执?
因為block中,引用的是weakSelf這個指針艾凯,而NSTimer引用的是weakSelf指針指向的內(nèi)存地址献幔,所以只要NSTimer不釋放,就會一直持有weakSelf指向的self趾诗,而因為timer被runloop強持有蜡感,runloop又是常駐的,所以timer一直沒有被釋放。
NSTimer解決循環(huán)引用的幾種方式:
1.離開頁面的時候郑兴,置空timer
2.ios 10之后犀斋,系統(tǒng)幫我們對NSTimer進行了block的封裝,防止block循環(huán)引用即可
3.做個中間類情连,幫助控制器持有NSTimer
4.用GCD的定時器

五:GCD什么情況下會開啟多線程叽粹?
1.同步函數(shù)串行隊列:
不會開啟新線程,在當(dāng)前線程執(zhí)行任務(wù)
任務(wù)串行執(zhí)行蒙具,一個接著一個
會產(chǎn)生死鎖
2.同步函數(shù)并行隊列:
不會開啟新線程球榆,在當(dāng)前線程執(zhí)行任務(wù)
任務(wù)依然一個接一個
3.異步函數(shù)串行隊列:
開啟一個新線程,任務(wù)一個接一個執(zhí)行
4.異步函數(shù)并行隊列:
開啟多個線程禁筏,任務(wù)并發(fā)執(zhí)行
5.創(chuàng)建隊列的方式:

- (void)test {
    //串行隊列
    dispatch_queue_t serial = dispatch_queue_create("com", DISPATCH_QUEUE_SERIAL);
    //并發(fā)隊列
    dispatch_queue_t concurrent = dispatch_queue_create("com", DISPATCH_QUEUE_CONCURRENT);
    //主隊列
    dispatch_queue_t mainQueue = dispatch_get_main_queue();
    //全局隊列
    dispatch_queue_t globalQueue = dispatch_get_global_queue(0, 0);
} 

根據(jù)官網(wǎng)介紹持钉,多線程創(chuàng)建需要耗費一定的內(nèi)核空間,主線程一般是1MB,非主線程一般是16Kb到512KB,創(chuàng)建線程的時間大概是90微秒篱昔,切換線程每强,也會消耗一定的資源時間

六:柵欄函數(shù)
1.dispatch_barrier_async: 當(dāng)前任務(wù)隊列中,前面的任務(wù)執(zhí)行完畢才會執(zhí)行barrier中的邏輯州刽,以及barrier后加入該隊列的任務(wù)空执,但是不影響該柵欄函數(shù)所在隊列后面函數(shù)的執(zhí)行。
2.dispatch_barrier_sync:作用相同穗椅,區(qū)別是會堵塞隊列后面的函數(shù)執(zhí)行辨绊。
舉例:

    dispatch_queue_t concurrentQueue = dispatch_queue_create("testQueue", DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(concurrentQueue, ^{
        NSLog(@"1");
    });
    dispatch_async(concurrentQueue, ^{
        NSLog(@"2");
    });
    dispatch_barrier_async(concurrentQueue, ^{
        NSLog(@"3:%@",[NSThread currentThread]);
    });
    dispatch_async(concurrentQueue, ^{
        NSLog(@"4");
    });
    NSLog(@"5");
} 

上面代碼打印出來的數(shù)據(jù),1,2,5的排序是不固定的匹表,门坷,但是3、4一定是最后兩個袍镀,3一定在4前面默蚌。
3.柵欄函數(shù)在全局隊列中是不生效的,因為全局隊列中苇羡,不僅有你的任務(wù)绸吸,還有其他系統(tǒng)的任務(wù),如果加barrier设江,不僅會影響你自己的任務(wù)锦茁,還會影響系統(tǒng)的任務(wù),對于全局隊列來說绣硝,barrier相當(dāng)于普通的異步函數(shù)蜻势。
4.柵欄函數(shù)可以當(dāng)成鎖來用:

NSMutableArray *array = [NSMutableArray array];
dispatch_queue_t concurrentQueue = dispatch_queue_create("testQueue", DISPATCH_QUEUE_CONCURRENT);
for (int i = 0; i < 1000; i++) {
    dispatch_async(concurrentQueue, ^{
        [array addObject:@(i)];
    });
}

上面代碼中,多線程操作一個數(shù)組array鹉胖,在addObject的時候有可能存在同一時間對同一塊內(nèi)存空間寫入數(shù)據(jù)(因為多線程是無序的握玛,i=4的時候和i=100的時候够傍,有可能i=100先運行,那么這時候往數(shù)組里插數(shù)據(jù)挠铲,就有可能數(shù)據(jù)錯誤冕屯,此時就會崩潰報錯)。
比如寫第3個數(shù)據(jù)的時候拂苹,當(dāng)前數(shù)組中數(shù)據(jù)是(1安聘,2)這個時候有2個線程同時寫入數(shù)據(jù)就存在了(1,2瓢棒,3)(1浴韭,2,4)這個時候數(shù)據(jù)就發(fā)生了混亂造成了錯誤脯宿。
將數(shù)組添加元素的操作放入dispatch_barrier_async中:

dispatch_queue_t concurrentQueue = dispatch_queue_create("Hotpot", DISPATCH_QUEUE_CONCURRENT);
for (int i = 0; i < 1000; i++) {
    dispatch_async(concurrentQueue, ^{
        dispatch_barrier_async(concurrentQueue , ^{
            [array addObject:@(i)];
        });
    });
}

七.信號量
dispatch_semaphore_create(long value);
初始化一個值為value的信號量,value等于幾念颈,就支持最多幾個線程并發(fā)訪問。

dispatch_semaphore_wait(dispatch_semaphore_t dsema, dispatch_time_t timeout);
此函數(shù)會讓信號量-1(通常來講连霉,我們會將信號量初始化為1)榴芳,信號量小于0,則線程進入堵塞跺撼、等待狀態(tài)窟感。

dispatch_semaphore_signal(dispatch_semaphore_t dsema);
此函數(shù)會釋放信號量,讓信號量+1歉井,信號量不為1柿祈,則該線程繼續(xù)執(zhí)行

信號量的作用:
1.可以限制并發(fā)隊列里最大并發(fā)數(shù)
2.配合線程組,解決多個網(wǎng)絡(luò)請求后哩至,統(tǒng)一刷新頁面谍夭、處理數(shù)據(jù)的問題
3.保護數(shù)據(jù)上鎖

 dispatch_queue_t queue = dispatch_queue_create("并發(fā)隊列", DISPATCH_QUEUE_CONCURRENT);
 NSMutableArray *array = [NSMutableArray array];
 dispatch_semaphore_t semaphore = dispatch_semaphore_create(1);
 for (int i = 0; i < 10000; i++) {
   dispatch_async(queue, ^{
       dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);//此時當(dāng)前并發(fā)隊列,只有一個線程能訪問
       NSLog(@"添加的值:%d  當(dāng)前線程%@",i,[NSThread currentThread]);
       [array addObject:@(i)];
       dispatch_semaphore_signal(semaphore);
   });
 }
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
dispatch_semaphore_t sem = dispatch_semaphore_create(0);

dispatch_async(queue, ^{
    dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
    NSLog(@"1 start");
    NSLog(@"1 end");
});//由于初始值為0憨募,wait后,信號量-1袁辈,小于0菜谣,所以后面的打印方法不執(zhí)行

dispatch_async(queue, ^{
    sleep(2);
    NSLog(@"2 start");
    NSLog(@"2 end");
    dispatch_semaphore_signal(sem);
});//此異步任務(wù)先執(zhí)行

打印出來的值:

2 start
2 end
1 start
1 end

八:線程組:
控制線程任務(wù)執(zhí)行順序,類似于柵欄函數(shù)的作用

dispatch_group_t group = dispatch_group_create();
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
dispatch_queue_t queue1 = dispatch_queue_create("test", DISPATCH_QUEUE_CONCURRENT);

dispatch_group_async(group, queue, ^{
    sleep(3);
    NSLog(@"1");
});

dispatch_group_async(group, queue1, ^{
    sleep(2);
    NSLog(@"2");
});

dispatch_group_async(group, queue1, ^{
    sleep(1);
    NSLog(@"3");
});

dispatch_group_async(group, queue, ^{
    NSLog(@"4");
});

dispatch_group_notify(group, dispatch_get_global_queue(0, 0), ^{
    NSLog(@"5");
});

任務(wù)5永遠在任務(wù)1晚缩、2尾膊、3、4之后執(zhí)行荞彼。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末冈敛,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子鸣皂,更是在濱河造成了極大的恐慌抓谴,老刑警劉巖暮蹂,帶你破解...
    沈念sama閱讀 211,123評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異癌压,居然都是意外死亡仰泻,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評論 2 384
  • 文/潘曉璐 我一進店門滩届,熙熙樓的掌柜王于貴愁眉苦臉地迎上來集侯,“玉大人,你說我怎么就攤上這事帜消√耐鳎” “怎么了?”我有些...
    開封第一講書人閱讀 156,723評論 0 345
  • 文/不壞的土叔 我叫張陵泡挺,是天一觀的道長辈讶。 經(jīng)常有香客問我,道長粘衬,這世上最難降的妖魔是什么荞估? 我笑而不...
    開封第一講書人閱讀 56,357評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮稚新,結(jié)果婚禮上勘伺,老公的妹妹穿的比我還像新娘。我一直安慰自己褂删,他們只是感情好飞醉,可當(dāng)我...
    茶點故事閱讀 65,412評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著屯阀,像睡著了一般缅帘。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上难衰,一...
    開封第一講書人閱讀 49,760評論 1 289
  • 那天钦无,我揣著相機與錄音,去河邊找鬼盖袭。 笑死失暂,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的鳄虱。 我是一名探鬼主播弟塞,決...
    沈念sama閱讀 38,904評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼拙已!你這毒婦竟也來了决记?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,672評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎宗挥,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體康栈,經(jīng)...
    沈念sama閱讀 44,118評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡笙瑟,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,456評論 2 325
  • 正文 我和宋清朗相戀三年楼镐,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片往枷。...
    茶點故事閱讀 38,599評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡框产,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出错洁,到底是詐尸還是另有隱情秉宿,我是刑警寧澤,帶...
    沈念sama閱讀 34,264評論 4 328
  • 正文 年R本政府宣布屯碴,位于F島的核電站描睦,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏导而。R本人自食惡果不足惜忱叭,卻給世界環(huán)境...
    茶點故事閱讀 39,857評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望今艺。 院中可真熱鬧韵丑,春花似錦、人聲如沸虚缎。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽实牡。三九已至陌僵,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間创坞,已是汗流浹背碗短。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留题涨,地道東北人豪椿。 一個月前我還...
    沈念sama閱讀 46,286評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像携栋,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子咳秉,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,465評論 2 348

推薦閱讀更多精彩內(nèi)容