一个尴尬的耗时处理

字数 397阅读 136

文章来源:
http://lexch.cn/2017/03/10/%E4%B8%80%E4%B8%AA%E5%B0%B4%E5%B0%AC%E7%9A%84%E8%80%97%E6%97%B6%E5%A4%84%E7%90%86/

耗时处理有很多种,今天在解决一个问题的时候 突然“萌”发了一个很有意思的解决方法这里分享一下
#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;
  }
}

那么我们再次测试一下!!!!!!!!!!


推荐阅读更多精彩内容