iOS多線程運(yùn)用

系列文章:

多線程

多線程 pthread、NSThread

多線程 GCD

多線程 NSOperation

多線程運(yùn)用

多線程運(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

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

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

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