在開發(fā)中遇到的一些多線程問題

來源 | https://blog.boolchow.com/,點(diǎn)擊閱讀原文查看作者更多文章
本文節(jié)選自作者 2018 年的《我所理解的 iOS 并發(fā)編程》,讀者小伙伴么在開發(fā)中遇到的并發(fā)問題,歡迎在留言區(qū)留言
1. NSNotification 與多線程問題
@implementation BLPostNotification
- (void)postNotification {
dispatch_queue_t queue = dispatch_queue_create("com.bool.post.notification", DISPATCH_QUEUE_SERIAL);
dispatch_async(queue, ^{
// 從非主線程發(fā)送通知 (通知名字最好定義成一個(gè)常量)
[[NSNotificationCenter defaultCenter] postNotificationName:@"downloadImage" object:nil];
});
}
@end
@implementation ImageViewController
- (void)viewDidLoad {
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(show) name:@"downloadImage" object:nil];
}
- (void)showImage {
// 需要 dispatch 到主線程更新 UI
dispatch_async(dispatch_get_main_queue(), ^{
// update UI
});
}
@end
2. NSTimer 與多線程問題
However, for a repeating timer, you must invalidate the timer object yourself by calling its?invalidate?method. Calling this method requests the removal of the timer from the current run loop; as a result, you should always call the?invalidate?method from the same thread on which the timer was installed.
@interface BLTimerTest ()
@property (nonatomic, strong) dispatch_queue_t queue;
@property (nonatomic, strong) NSTimer *timer;
@end
@implementation BLTimerTest
- (instancetype)init {
self = [super init];
if (self) {
_queue = dispatch_queue_create("com.bool.timer.test", DISPATCH_QUEUE_SERIAL);
}
return self;
}
- (void)installTimer {
dispatch_async(self.queue, ^{
self.timer = [NSTimer scheduledTimerWithTimeInterval:3.0f repeats:YES block:^(NSTimer * _Nonnull timer) {
NSLog(@"test timer");
}];
});
}
- (void)clearTimer {
dispatch_async(self.queue, ^{
if ([self.timer isValid]) {
[self.timer invalidate];
self.timer = nil;
}
});
}
@end
3. Dispatch Once 死鎖問題
- (void)dispatchOnceTest {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
[self dispatchOnceTest];
});
}
4. Dispatch Group 問題
- (void)testDispatchGroup {
NSString *path = @"";
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *folderList = [fileManager contentsOfDirectoryAtPath:path error:nil];
dispatch_group_t taskGroup = dispatch_group_create();
for (NSString *folderName in folderList) {
dispatch_group_enter(taskGroup);
NSString *folderPath = [@"path" stringByAppendingPathComponent:folderName];
NSArray *fileList = [fileManager contentsOfDirectoryAtPath:folderPath error:nil];
for (NSString *fileName in fileList) {
dispatch_async(_queue, ^{
// 異步任務(wù)
dispatch_group_leave(taskGroup);
});
}
}
}
推薦閱讀
如何把 if-else 重構(gòu)成高質(zhì)量代碼?
用 Java 寫了一個(gè)類 QQ 界面聊天小項(xiàng)目,可在線聊天!
點(diǎn)個(gè)『在看』支持下?
評(píng)論
圖片
表情

