dispatch_group封装

2021-02-22  本文已影响0人  championfu

之所以封装是因为,dispatch_group_leave()先执行会导致崩溃,为了安全执行性,进行封装

.h文件

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN


/// 建立此类的原因,在P操作执行之前,不能执行V操作,因此需要对信号量进行判断
@interface DispatchGroup : NSObject


/// P操作,信号量减少1
- (void)enter;

/// V操作,信号量增加1,PV操作成对出现,且不能提前V操作
- (void)leave;


/// 异步执行一个任务,相当于在某队列中执行了一次PV操作
/// @param queue 执行队列
/// @param block 任务回调
- (void)asyncOnQueue:(dispatch_queue_t)queue block:(dispatch_block_t)block;

/// 监听PV操作完成后的回调,此函数不会释放group
- (void)notifyOnQueue:(dispatch_queue_t)queue block:(dispatch_block_t)block;


/// 超时执行,此函数会在超时后释放group
/// @param queue 执行队列 NULL为 dispatch_get_global_queue(0,0)
/// @param inteval 超时时间 =0:不等待,>0:期限等待 <0:永久等待
/// @param block YES 超时,NO,不超时
- (void)waitOnQueue:(nullable dispatch_queue_t)queue inteval:(NSTimeInterval)inteval block:(void(^)(BOOL isTimeout))block;

@end

NS_ASSUME_NONNULL_END

.m文件

//
//  DispatchGroup.m
//  LPDoorBell
//
//  Created by Champion Fu on 2021/2/22.
//  Copyright © 2021 lancens_app. All rights reserved.
//

#import "DispatchGroup.h"

@implementation DispatchGroup {
    dispatch_group_t _group;
    NSInteger _semaphoreValue;
}

- (instancetype)init
{
    self = [super init];
    if (self) {
        _semaphoreValue = LONG_MAX;
        _group = dispatch_group_create();
    }
    return self;
}

- (void)enter {
    _semaphoreValue -= 1;
    dispatch_group_enter(_group);
}

- (void)leave {
    if (_semaphoreValue < LONG_MAX) {
        _semaphoreValue += 1;
        dispatch_group_leave(_group);
    }
}

- (void)asyncOnQueue:(dispatch_queue_t)queue block:(dispatch_block_t)block {
    dispatch_group_async(_group, queue, block);
}

- (void)notifyOnQueue:(dispatch_queue_t)queue block:(dispatch_block_t)block {
    dispatch_group_notify(_group, queue, block);
}

- (void)waitOnQueue:(nullable dispatch_queue_t)queue inteval:(NSTimeInterval)inteval block:(void(^)(BOOL isTimeout))block {
    if (!queue) queue = dispatch_get_global_queue(0, 0);
    dispatch_async(queue, ^{
        dispatch_time_t time;
        if (inteval < 0) {
            time = DISPATCH_TIME_FOREVER;
        }else {
            time = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(inteval * NSEC_PER_SEC));
        }
        intptr_t result = dispatch_group_wait(self->_group, time);
        block(result != 0);
    });
}



@end

上一篇下一篇

猜你喜欢

热点阅读