您的位置:首页 > 移动开发 > IOS开发

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

2016-11-24 23:09 656 查看

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);
});
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: