耗时处理有很多种,今天在解决一个问题的时候 突然“萌”发了一个很有意思的解决方法这里分享一下
#import <Foundation/Foundation.h>
@interface LEXObject : NSObject
@property (nonatomic,strong)NSString *name;
@end
我现在需要从网络获取这个name,但是我又不想每个地方都写一遍网络请求,就为了这么一个值。。。。
然后就出现啦下面的情况
#import "LEXObject.h"
@implementation LEXObject
- (NSString *)name{
dispatch_group_t group = dispatch_group_create();
if (_name == nil) {
dispatch_group_enter(group);
[self analogNetworkRequestComplete:^(id result) {
_name = result;
dispatch_group_leave(group);
}];
}
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
return _name;
}
//模拟一个网络请求
- (void)analogNetworkRequestComplete:(void(^)(id))complete{
sleep(4);
complete(@"massimo");
}
@end
因为之前用到好多 dispatch_group 所以这里的场景感觉用它很顺手
- (IBAction)somethingUpdate{
// 因为是获取 obj.name 是一个耗时事件 所以我们放在dispatch_get_global_queue(0, 0)中 否则会阻塞主线程
dispatch_async(dispatch_get_global_queue(0, 0), ^{
LEXObject *obj = [[LEXObject alloc] init];
NSLog(@"get obj.name ---%@",[NSDate date]);
NSString *getSomestring = obj.name;
NSLog(@"obj.name : %@ ---%@",getSomestring,[NSDate date]);
dispatch_async(dispatch_get_main_queue(), ^{
// 执行下面的事情
// some codes;
});
});
}
恩 最后实际应用到这里
是不是很简洁 哈哈
像这种应用情况还是看具体业务吧!没有什么一劳永逸,咱还得是见招拆招不是!!
-----------------------------------2017.03.11---------------更新-------------------------
今天休息 , 感觉这篇文章有些欠考虑的地方,然后就加了一点小改进
#import "ViewController.h"
#import "FirstSDK.h"
@interface ViewController ()
@property (nonatomic, strong)LexObject *obj;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
_obj = [[LexObject alloc]init];
}
- (IBAction)clickMe:(id)sender
{
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSLog(@"----begin");
NSLog(@"%@",_obj.name);
NSLog(@"----finish");
});
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
就是当我将obj当成一个全局属性的时候,那么当有多个线程同时获取name的时候,这个name为nil,就会多次执行if语句里的代码;
这时候我们用到了线程锁------------@synchronized
- (NSString *)name{
@synchronized (self) {
NSLog(@"loading............");
dispatch_group_t group = dispatch_group_create();
if (_name == nil) {
dispatch_group_enter(group);
[self networkRequest:^(id success) {
_name = success;
dispatch_group_leave(group);
}];
}
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
return _name;
}
}
那么我们再次测试一下!!!!!!!!!!