iOS 开发 多线程详解之GCD应用延迟操作,单例设计模式,调度组

GCD延时操作

特点:时间特别精确

- (void)afterDemo {
    NSLog(@"start");

    /*
     参数1 : dispatch_time_t when : 延迟多长时间,精确到纳秒
     参数2 : dispatch_queue_t queue : 在哪个队列
     参数3 : dispatch_block_t block : 执行哪个任务
     */

    // 参数1 : dispatch_time_t when : 延迟多长时间
    dispatch_time_t when = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC));
    // 参数2 : dispatch_queue_t queue : 在哪个队列
//    dispatch_queue_t queue = dispatch_get_main_queue();
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    // 参数3 : dispatch_block_t block : 执行哪个任务
    dispatch_block_t block = ^{

        NSLog(@"终于执行了 %@",[NSThread currentThread]);
    };

    // 结论 : 这个函数是个异步函数
    dispatch_after(when, queue, block);

    NSLog(@"mark");
}
//项目应用  
    [[NetworkTool shareNetworkTool] requestWithType:requestTypePOST URLString:URLString parameters:parameters progress:nil success:^(NSURLSessionDataTask * _Nullable task, id  _Nullable responseObject) {

        NSString *data = responseObject[@"data"];
        if ([data isEqualToString:@"success"]) {

        //想要操作成功时出现提示弹框后,再实现跳转
            [SVProgressHUD showWithStatus:@"成功"];
//可以在这里使用dispatch_after操作
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                [SVProgressHUD dismiss];
                [self.navigationController pushViewController:[[SellOrderController alloc] init] animated:YES];
            }); 
        }

    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        ZYLog(@"%@",error);
    }];

dispatch_once_t和单例设计模式

/*
1.保存在内存的静态存储区
2.生命周期跟APP一样长
3.有一个供全局实例化单例的类方法
4.在内存中有且只有一个实例化的对象
*/
最基本的单例设计模式

// 这种写法是满足开发的需求的
+ (instancetype)shareNetworkTool {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[NetworkTool alloc]init];
        //  让AFN默认也支持接收text/html文件类型
        instance.responseSerializer.acceptableContentTypes
        = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript", @"text/html",@"text/plain", nil];
    });
    return instance;
}

//最安全的单例设计模式—维护老项目(ARC和MRC混合开发)

static AccountManager *instance;

#if __has_feature(objc_arc) // ARC
//ARC下单例设计模式
+ (instancetype)sharedAccountManager {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[AccountManager alloc] init];
    });

    return instance;
}

+ (instancetype)allocWithZone:(struct _NSZone *)zone {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [super allocWithZone:zone];
    });

    return instance;
}

- (id)copyWithZone:(NSZone *)zone {
    return instance;
}

#else // MRC
//MRC下单例设计模式
+ (instancetype)sharedAccountManager {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[AccountManager alloc] init];
    });

    return instance;
}

+ (instancetype)allocWithZone:(struct _NSZone *)zone {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [super allocWithZone:zone];
    });

    return instance;
}

- (id)copyWithZone:(NSZone *)zone {
    return instance;
}

- (oneway void)release {
    // 什么都不做
}

- (instancetype)retain {
    return instance;
}

- (instancetype)autorelease {
    return instance;
}

/// 永远保证引用计数为1
- (NSUInteger)retainCount {
    return 1;
}

#endif

调度组(group)

//案例-:多张图片异步都下载完成后再合成一张图片
//案例二:类似于QQ空间动态列表展示时,如果是单张图片,希望图片下载后,根据图片的大小来展示,多张图片展示规定的尺寸
- (void)groupDemo1 {
    // 调度组
    dispatch_group_t group = dispatch_group_create();

    // 队列
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);

    dispatch_group_async(group, queue, ^{
        NSLog(@"下载图片A...%@",[NSThread currentThread]);
    });

    dispatch_group_async(group, queue, ^{
        NSLog(@"下载图片B...%@",[NSThread currentThread]);
    });

    dispatch_group_async(group, queue, ^{
        NSLog(@"下载图片C...%@",[NSThread currentThread]);
    });

    // 监听 group 里面的所有的异步任务是否执行完,如果执行完就自动的执行dispatch_group_notify这个函数
    // 异步监听
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        // 写图片下载完成之后的代码
        NSLog(@"刷新UI %@",[NSThread currentThread]);
    });

    // DISPATCH_TIME_FOREVER : 监听group里面的任务是否都执行完,直到永远(不执行完,后面的代码都不执行)
    // 阻塞
//    dispatch_group_wait(group, DISPATCH_TIME_FOREVER);

    NSLog(@"mark");
}
/// 调度组实现原理
dispatch_group_async(dispatch_group_t group, dispatch_queue_t queue, dispatch_block_t block)
{
    dispatch_group_enter(group);
    dispatch_async(queue, ^{
        block();
        dispatch_group_leave(group);
    });
}

    // 下载图片A
    // 1.为图片A的下载操作,向group里面添加标记
    dispatch_group_enter(group);
    // 2.实现异步下载
    dispatch_async(queue, ^{
        NSLog(@"下载图片A...%@",[NSThread currentThread]);

        // 3.这个图片下载完成,说明任务结束,那么把这个任务对应的标记从group移除
        dispatch_group_leave(group);
    });

你可能感兴趣的:(多线程,iOS开发)