系列文章:
多線程運(yùn)用
線程同步
所謂線程同步就是為了防止多個(gè)線程搶奪同一個(gè)資源造成的數(shù)據(jù)安全問題,所采取的一種措施。當(dāng)然也有很多實(shí)現(xiàn)方法,請(qǐng)往下看:
- 互斥鎖 :給需要同步的代碼塊加一個(gè)互斥鎖,就可以保證每次只有一個(gè)線程訪問此代碼塊。
OBJECTIVE-C
@synchronized(self) {
//需要執(zhí)行的代碼塊
}
SWIFT
objc_sync_enter(self)
//需要執(zhí)行的代碼塊
objc_sync_exit(self)
- 同步執(zhí)行 :我們可以使用多線程的知識(shí),把多個(gè)線程都要執(zhí)行此段代碼添加到同一個(gè)串行隊(duì)列,這樣就實(shí)現(xiàn)了線程同步的概念。當(dāng)然這里可以使用 GCD 和 NSOperation 兩種方案:
//GCD
//需要一個(gè)全局變量queue,要讓所有線程的這個(gè)操作都加到一個(gè)queue中
dispatch_sync(queue, ^{
NSInteger ticket = lastTicket;
[NSThread sleepForTimeInterval:0.1];
NSLog(@"%ld - %@",ticket, [NSThread currentThread]);
ticket -= 1;
lastTicket = ticket;
});
//NSOperation & NSOperationQueue
//重點(diǎn): 1. 全局的 NSOperationQueue, 所有的操作添加到同一個(gè)queue中
// 2. 設(shè)置 queue 的 maxConcurrentOperationCount 為 1
// 3. 如果后續(xù)操作需要Block中的結(jié)果,就需要調(diào)用每個(gè)操作的waitUntilFinished,阻塞當(dāng)前線程,一直等到當(dāng)前操作完成,才允許執(zhí)行后面的。waitUntilFinished 要在添加到隊(duì)列之后!
NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
NSInteger ticket = lastTicket;
[NSThread sleepForTimeInterval:1];
NSLog(@"%ld - %@",ticket, [NSThread currentThread]);
ticket -= 1;
lastTicket = ticket;
}];
[queue addOperation:operation];
[operation waitUntilFinished];
//后續(xù)要做的事
延遲執(zhí)行
所謂延遲執(zhí)行就是延時(shí)一段時(shí)間再執(zhí)行某段代碼。下面說一些常用方法。
- perform
// 3秒后自動(dòng)調(diào)用self的run:方法,并且傳遞參數(shù):@"abc"
[self performSelector:@selector(run:) withObject:@"abc" afterDelay:3];
- GCD
可以使用 GCD 中的 dispatch_after 方法
// 創(chuàng)建隊(duì)列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// 設(shè)置延時(shí),單位秒
double delay = 3;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delay * NSEC_PER_SEC)), queue, ^{
// 3秒后需要執(zhí)行的任務(wù)
});
- NSTimer
NSTimer 是iOS中的一個(gè)計(jì)時(shí)器類,除了延遲執(zhí)行還有很多用法,不過這里直說延遲執(zhí)行的用法。
[NSTimer scheduledTimerWithTimeInterval:3.0 target:self selector:@selector(run:) userInfo:@"abc" repeats:NO];
單例模式
static HLUserManager *_singleton = nil;
@implementation HLUserManager
+ (instancetype)sharedManager {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_singleton = [[HLUserManager alloc] init];
});
return _singleton;
}
@end
下面看 Swift 中的單例模式,在Swift中單例模式非常簡(jiǎn)單!想知道怎么從 OC 那么復(fù)雜的方法變成下面的寫法的,請(qǐng)看這里
SWIFT
class Tool: NSObject {
static let sharedTool = Tool()
// 私有化構(gòu)造方法,阻止其他對(duì)象使用這個(gè)類的默認(rèn)的'()'構(gòu)造方法
private override init() {}
}
從其他線程回到主線程的方法
我們都知道在其他線程操作完成后必須到主線程更新UI。所以,介紹完所有的多線程方案后,我們來看看有哪些方法可以回到主線程。
- NSThread
//Objective-C
[self performSelectorOnMainThread:@selector(run) withObject:nil waitUntilDone:NO];
//Swift
//swift 取消了 performSelector 方法。
- GCD
//Objective-C
dispatch_async(dispatch_get_main_queue(), ^{
});
//Swift
dispatch_async(dispatch_get_main_queue(), { () -> Void in
})
- NSOperationQueue
//Objective-C
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
}];
//Swift
NSOperationQueue.mainQueue().addOperationWithBlock { () -> Void in
}