遇到xib的知識
NSBundle
- (文檔原話)Many of the methods you use to load resources from a bundle automatically locate the appropriate starting directory and look for resources in known places
- (blog摘抄)bundle是一個目錄,其中包含了程序會使用到的資源.這些資源包含了如圖像,聲音,編譯好的代碼,nib文件(用戶也會把bundle稱為plug-in).對應(yīng)bundle,cocoa提供了類NSBundle.
結(jié)合蘋果的開發(fā)文檔和別人blog羡铲,模糊地理解為bundle能提供一個方式(就是獲取文件路徑
)讓我們從bundel里面讀取我們需要的東西。文檔列舉了3中project類型
Application, Framework, plug-ins。這里我們會用除了這三個外的在程序上讀取nib文件或者圖片。
//讀取nib文件的方法
-(NSArray *)loadNibNamed:(NSString *)*name*
owner:(id)*owner*
options:(NSDictionary *)*options*
返回一個nib里面所有view的數(shù)組娶耍。
注意:
1· 這個數(shù)組不包含F(xiàn)iles owner或者代理對象钢拧。
總結(jié):
- 這里引用的blog我都嘗試跟著做了一遍,稍微有些名目栏赴。平時開發(fā)時常喜歡按著control鍵拉線盈咳,outlet翻譯就是出口的意思耿眉,我感覺就是在xib的fileown關(guān)聯(lián)文件之后,如果需要顯示xib上的view時候鱼响,就需要使用outlet鸣剪。如果不使用這個,就需要使用以上NSbundle的方法去引用xib文件的內(nèi)容
- 其實(shí)無論是使用bundle的方法還是在xib引用file`s owner丈积,最主要就是知道file·s owner是誰筐骇,這樣就可以在該文件使用bundle方法引用xib內(nèi)容,或者使用outlet桶癣。 對了 這里說的拉線,是關(guān)于.h文件和xib文件娘锁,也就是定義一個IBOutlet與xib關(guān)聯(lián)牙寞。并不是說使用bundle就不用再xib里面對files owner和view關(guān)聯(lián)!莫秆!
xib還可以動態(tài)橋接间雀,這些以后有空補(bǔ)回來!
這里是GCD初入門學(xué)習(xí)
這篇東西好久沒寫了镊屎,上次有心思寫博客的時候是過年左右吧惹挟,并不是應(yīng)付面試學(xué)習(xí),當(dāng)是看的是GCD深入理解缝驳,里面的東西確實(shí)很多连锯,而且越看越發(fā)現(xiàn)自己需要補(bǔ)的知識就越多归苍,到了最后都忘記自己是在學(xué)iOS線程這東西了。如果看的也覺得忒多的話运怖,我這里給兩個比較簡單明了拼弃,而且結(jié)合起來能有不錯理解的blog。
(1)關(guān)于多線程你看我就夠了
(2)死鎖的五個案例
第一個blog里面關(guān)于死鎖的原因沒解釋的很清楚摇展,因此我自己又找了一個blog吻氧,后面的解釋的很清楚,還看不懂我也沒辦法了咏连。
Pthreads
一般我們這些初級的盯孙,還用不到這么底層的東西,所以直接跳過祟滴,有興趣的可以在操作系統(tǒng)的內(nèi)容里面看到振惰。
NSThread
在我的說法里就是需要自己管理線程的整個生命周期,這個肯定能說有好有壞踱启,一般好的就是說自己管理效率上或者自定義方面比較好嘛报账,不好的肯定就是相對于封裝好的使用比較麻煩嘛。但是這東西我們很多時候也會用例如 [NSThread currentThread]埠偿;
具體的使用方法透罢,以及有什么方法調(diào)用,我也不貼了冠蒋,自己進(jìn)去文件里面看更加詳細(xì)羽圃。
NSOperation和NSOperationQueue
GCD
終于到了重點(diǎn)了。Grand Central Dispatch抖剿。蘋果為多核處理器提出并行運(yùn)算提出來的方案朽寞,其實(shí)也就是為了讓多核能更好的使用罷了。因為一個系統(tǒng)需要同時執(zhí)行的進(jìn)程估計會很多吧斩郎,多了一個脑融,但其實(shí)遠(yuǎn)遠(yuǎn)還不夠,而且還要考慮作業(yè)調(diào)度的問題缩宜。肘迎。。下面科普一些術(shù)語锻煌。
串行&并發(fā)
這些術(shù)語描述當(dāng)任務(wù)相對于其它任務(wù)被執(zhí)行妓布,任務(wù)串行執(zhí)行就是每次只有一個任務(wù)被執(zhí)行,任務(wù)并發(fā)執(zhí)行就是在同一時間可以有多個任務(wù)被執(zhí)行宋梧。
同步&異步
一個同步函數(shù)只在完成了它預(yù)定的任務(wù)后才返回匣沼。
一個異步函數(shù),剛好相反捂龄,會立即返回释涛,預(yù)定的任務(wù)會完成但不會等它完成加叁。因此,一個異步函數(shù)不會阻塞當(dāng)前線程去執(zhí)行下一個函數(shù)枢贿。
臨界區(qū)
就是一段代碼不能被并發(fā)執(zhí)行殉农,也就是,兩個線程不能同時執(zhí)行這段代碼局荚。
死鎖
兩個(有時更多)東西——在大多數(shù)情況下超凳,是線程——所謂的死鎖是指它們都卡住了,并等待對方完成或執(zhí)行其它操作耀态。第一個不能完成是因為它在等待第二個的完成轮傍。但第二個也不能完成,因為它在等待第一個的完成首装。
上下文切換
一個上下文切換指當(dāng)你在單個進(jìn)程里切換執(zhí)行不同的線程時存儲與恢復(fù)執(zhí)行狀態(tài)的過程创夜。
線程安全
線程安全的代碼能在多線程或并發(fā)任務(wù)中被安全的調(diào)用,而不會導(dǎo)致任何問題(數(shù)據(jù)損壞仙逻,崩潰驰吓,等)。線程不安全的代碼在某個時刻只能在一個上下文中運(yùn)行系奉。一個線程安全代碼的例子是 NSDictionary 檬贰。你可以在同一時間在多個線程中使用它而不會有問題。另一方面缺亮,NSMutableDictionary 就不是線程安全的翁涤,應(yīng)該保證一次只能有一個線程訪問它。
并發(fā)并行Concurrency vs Parallelism
并發(fā): 一個很短的時間間隔內(nèi)同時發(fā)生兩個線程
并行:同時運(yùn)行兩個線程
創(chuàng)建隊列
//獲取主線程
dispatch_queue_t queue = dispatch_get_main_queue();
- 主隊列:這是一個特殊的 串行隊列萌踱。什么是主隊列葵礼,大家都知道吧,它用于刷新 UI并鸵,任何需要刷新 UI 的工作都要在主隊列執(zhí)行鸳粉,所以一般耗時的任務(wù)都要放到別的線程執(zhí)行。
//一般的寫法
dispatch_queue_t queue= dispatch_queue_create("tk.bourne.testQueue", NULL);
- 自己創(chuàng)建的隊列:凡是自己創(chuàng)建的隊列都是 串行隊列园担。其中第一個參數(shù)是標(biāo)識符届谈,用于 DEBUG 的時候標(biāo)識唯一的隊列,可以為空粉铐。大家可以看xcode的文檔查看參數(shù)意義疼约。
更新:自己可以創(chuàng)建 串行隊列, 也可以創(chuàng)建 并行隊列卤档◎茫看下面的代碼(代碼已更新),它有兩個參數(shù)劝枣,第一個上面已經(jīng)說了汤踏,第二個才是最重要的织鲸。
第二個參數(shù)用來表示創(chuàng)建的隊列是串行的還是并行的,傳入 DISPATCH_QUEUE_SERIAL 或 NULL 表示創(chuàng)建串行隊列溪胶。傳入 DISPATCH_QUEUE_CONCURRENT 表示創(chuàng)建并行隊列搂擦。
- 全局并行隊列:這應(yīng)該是唯一一個并行隊列,只要是并行任務(wù)一般都加入到這個隊列哗脖。
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
創(chuàng)建任務(wù)
同步任務(wù):不會另開線程 (SYNC)
dispatch_sync(, ^{
//code here
NSLog(@"%@", [NSThread currentThread]);
});異步任務(wù):會另開線程 (ASYNC)
dispatch_async(, ^{
//code here
NSLog(@"%@", [NSThread currentThread]);
});
示例:
NSLog("之前 - %@", NSThread.currentThread())
dispatch_sync(dispatch_get_main_queue(), {
NSLog("sync - %@", NSThread.currentThread())
})
NSLog("之后 - %@", NSThread.currentThread())
這里只會輸出“之前” 瀑踢,因為后兩個輸出都被阻塞,原因是為什么呢才避?
當(dāng)前使用主線程執(zhí)行UI以及輸出“sync”這段橱夭,但是這兩個任務(wù)放在了當(dāng)前的主線程隊列---front- 刷新UI---輸出“sync”--rear
但是因為刷新UI需要等輸出“sync”完成了才能繼續(xù),但是串行執(zhí)行任務(wù)的原因輸出“sync”又把當(dāng)前線程阻塞了桑逝,所以刷新UI也不能執(zhí)行了棘劣。
對列組
隊列組可以將很多隊列添加到一個組里,這樣做的好處是楞遏,當(dāng)這個組里所有的任務(wù)都執(zhí)行完了茬暇,隊列組會通過一個方法通知我們。下面是使用方法寡喝,這是一個很實(shí)用的功能糙俗。
//1.創(chuàng)建隊列組
dispatch_group_t group = dispatch_group_create();
//2.創(chuàng)建隊列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//3.多次使用隊列組的方法執(zhí)行任務(wù), 只有異步方法
//3.1.執(zhí)行3次循環(huán)
dispatch_group_async(group, queue, ^{
for (NSInteger i = 0; i < 3; i++) {
NSLog(@"group-01 - %@", [NSThread currentThread]);
}
});
//3.2.主隊列執(zhí)行8次循環(huán)
dispatch_group_async(group, dispatch_get_main_queue(), ^{
for (NSInteger i = 0; i < 8; i++) {
NSLog(@"group-02 - %@", [NSThread currentThread]);
}
});
//3.3.執(zhí)行5次循環(huán)
dispatch_group_async(group, queue, ^{
for (NSInteger i = 0; i < 5; i++) {
NSLog(@"group-03 - %@", [NSThread currentThread]);
}
});
//4.都完成后會自動通知
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"完成 - %@", [NSThread currentThread]);
});
線程同步
- 互斥鎖 :給需要同步的代碼塊加一個互斥鎖,就可以保證每次只有一個線程訪問此代碼塊拘荡。
@synchronized(self) {
//需要執(zhí)行的代碼塊
}
延時執(zhí)行
perform
// 3秒后自動調(diào)用self的run:方法臼节,并且傳遞參數(shù):@"abc"
[self performSelector:@selector(run:) withObject:@"abc" afterDelay:3];GCD 可以使用 GCD 中的 dispatch_after 方法
// 創(chuàng)建隊列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// 設(shè)置延時,單位秒
double delay = 3;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delay * NSEC_PER_SEC)), queue, ^{
// 3秒后需要執(zhí)行的任務(wù)
});NSTimer
NSTimer 是iOS中的一個計時器類珊皿,除了延遲執(zhí)行還有很多用法网缝,不過這里直說延遲執(zhí)行的用法
[NSTimer scheduledTimerWithTimeInterval:3.0 target:self selector:@selector(run:) userInfo:@"abc" repeats:NO];
單例模式
@interface Tool : NSObject
+ (instancetype)sharedTool;
@end
@implementation Tool
static id _instance;
+ (instancetype)sharedTool {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [[Tool alloc] init];
});
return _instance;
}
@end
從其他線程回到主線程的方法
我們都知道在其他線程操作完成后必須到主線程更新UI。所以蟋定,介紹完所有的多線程方案后粉臊,我們來看看有哪些方法可以回到主線程。
- NSThread
//Objective-C
[self performSelectorOnMainThread:@selector(run) withObject:nil waitUntilDone:NO]; - GCD
//Objective-C
dispatch_async(dispatch_get_main_queue(), ^{
});