• 爱情文章
  • 亲情文章
  • 友情文章
  • 生活随笔
  • 校园文章
  • 经典文章
  • 人生哲理
  • 励志文章
  • 搞笑文章
  • 心情日记
  • 英语文章
  • 范文大全
  • 作文大全
  • 新闻阅读
  • 当前位置: 山茶花美文网 > 英语文章 > 正文

    什么时候用信号量 什么时候用队列【iOS开发:队列和信号量该如何同步】

    时间:2020-03-28来源:山茶花美文网 本文已影响 山茶花美文网手机站

    针对这个问题,我想到了两种解决方案:第一就是执行这些操作之前先判断是否已经初始化,如果尚未初始化则使用一个数组队列把操作参数及调用的方法存储起来,等待初始化完成后再检测数组队列中的保存的操作进行调用并清空队列。但这种方式有个问题就是操作中传递的参数以及调用方法引用都需要自己来维护,这无疑是给自己带来了一定的工作量以及风险,稍有不慎就有可能会导致内存泄露。

    因此第二中解决方法就是利用串行队列结合信号量的方式来控制操作的执行。此方案的思路是,先创建一条串行队列,此队列用于执行所有的操作。但是最先入队的是一个等待信号的操作。而这个信号的初始值是0,直到初始化操作完成后才会发送一个信号来通知此操作。因此,在尚未初始化完成的时候此队列是一直处于阻塞状态的。所以到有操作进入队列时都会立刻执行,而是需要等到初始化信号过来后才开始执行。

    为了验证这一想法,我新建了一个应用工程,在ViewController中定义了操作队列_quque和信号量_sema,如下:

    @interface ViewController : UIViewController

    {

    @private

    dispatch_queue_t _queue;

    dispatch_semaphore_t _sema;

    }

    @end

    初始化时创建操作队列

    - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil

    {

    if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])

    {

    _queue = dispatch_queue_create("cn.vimfung.demo", DISPATCH_QUEUE_SERIAL);

    }

    return self;

    }

    在ViewController中定义了三个按钮,分别为DoSomething、Signal、Wait。其中DoSomething为执行的操作。Signal为通知阻塞队列可以执行操作了。Wait为阻塞当前队列。

    - (void)viewDidLoad

    {

    [super viewDidLoad];

    // Do any additional setup after loading the view, typically from a nib.

    UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];

    [btn setTitle:@"DoSomething" forState:UIControlStateNormal];

    [btn sizeToFit];

    [btn addTarget:self action:@selector(doSomethingHandler:) forControlEvents:UIControlEventTouchUpInside];

    [self.view addSubview:btn];

    UIButton *btn1 = [UIButton buttonWithType:UIButtonTypeRoundedRect];

    [btn1 setTitle:@"Signal" forState:UIControlStateNormal];

    [btn1 sizeToFit];

    [btn1 addTarget:self action:@selector(signalHanlder:) forControlEvents:UIControlEventTouchUpInside];

    btn1.frame = CGRectMake(0.0, 50.0, btn1.frame.size.width, btn1.frame.size.height);

    [self.view addSubview:btn1];

    UIButton *btn2 = [UIButton buttonWithType:UIButtonTypeRoundedRect];

    [btn2 setTitle:@"Wait" forState:UIControlStateNormal];

    [btn2 sizeToFit];

    [btn2 addTarget:self action:@selector(waitHanlder:) forControlEvents:UIControlEventTouchUpInside];

    btn2.frame = CGRectMake(0.0, 100.0, btn2.frame.size.width, btn2.frame.size.height);

    [self.view addSubview:btn2];

    }

    - (void)doSomethingHandler:(id)sender

    {

    dispatch_async(_queue, ^{

    NSLog(@"do something");

    });

    }

    - (void)signalHanlder:(id)sender

    {

    dispatch_semaphore_signal(_sema);

    }

    - (void)waitHanlder:(id)sender

    {

    if (_sema)

    {

    dispatch_release(_sema);

    }

    _sema = dispatch_semaphore_create(0);

    dispatch_async(_queue, ^{

    dispatch_semaphore_wait(_sema, DISPATCH_TIME_FOREVER);

    });

    }

    运行后,先点击Wait让队列阻塞、然后这时无论怎么点击DoSomething都是不会有log信息显示,直到点击Signal后,之前点击的DoSomething将会一一打印出来信息。

    可见这种解决方案是可行的,并且可以更加容易操作。

    • 什么时候用信号量 什么时候用队列【iOS开发:队列和信号量该如何同步】 相关文章:
    • 爱情文章
    • 亲情文章
    • 友情文章
    • 随笔
    • 哲理
    • 励志
    • 范文大全