手机
当前位置:查字典教程网 >编程开发 >IOS开发 >iOS开发:队列和信号量该如何同步
iOS开发:队列和信号量该如何同步
摘要:针对这个问题,我想到了两种解决方案:第一就是执行这些操作之前先判断是否已经初始化,如果尚未初始化则使用一个数组队列把操作参数及调用的方法存储...

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

因此第二中解决方法就是利用串行队列结合信号量的方式来控制操作的执行。此方案的思路是,先创建一条串行队列,此队列用于执行所有的操作。但是最先入队的是一个等待信号的操作。而这个信号的初始值是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开发:队列和信号量该如何同步】相关文章:

iOS开发:UIView动画详解

iOS应用设计模式开发中对简单工厂和工厂方法模式的运用

iOS开发中CAlayer层的属性以及自定义层的方法

iOS简单画板开发案例分享

iOS屏幕适配开发实用技巧

IOS开发:如何挂起主线程

iOS开发之如何截图and如何合并多张图片等...

iOS开发中使用SQL语句操作数据库的基本用法指南

详解iOS App中UISwitch开关组件的基本创建及使用方法

解析iOS应用的UI开发中懒加载和xib的简单使用方法

精品推荐
分类导航