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将会一一打印出来信息。

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

时间: 2024-12-31 02:22:12

iOS开发:队列和信号量该如何同步的相关文章

iOS开发那些事-iOS网络编程同步GET方法请求编程

iOS SDK为HTTP请求提供了同步和异步请求两种不同的API,而且可以使用GET或POST等请求方法.我们先了解其中最为简单的同步GET方法请求. 为了学习这些API的使用MyNotes"备忘录"应用实例,数据来源于服务器端,而不是本地的Notes.xml(或Notes.json)文件. 首先实现查询业务,查询业务请求可以在主视图控制器MasterViewController类中实现,其中MasterViewController.h代码如下: #import <UIKit/U

ios开发-如何用从服务器获取的时间来对程序中的时间进行同步。

问题描述 如何用从服务器获取的时间来对程序中的时间进行同步. 在IOS开发中,如何用从服务器获取的时间来对程序中的时间进行同步. 解决方案 使程序调用服务器时间调用服务器时间的倒计时程序获取数据库服务器时间

IOS开发之多线程 -- GCD的方方面面

前言:这篇GCD的博文是本人阅读了很多海内外大神的关于GCD的文章,以及结合之前自己对GCD的粗浅的认识,然后取其精华,去其槽粕,综合起来的笔记,而且是尽可能的以通熟易懂的并且是正确的理论论述方式呈现给读者,同时也是讲大神博客中有的深涩的理论理解的通熟易懂转述给读者,已经是尽可能的让读者深入理解和掌握多线程的知识以及GCD的使用技术.最后的附录中,我将会给出所有本人阅读的大神写的关于多线程或者是GCD的文章链接,大家感兴趣的,可以去参考和学习.也许,看我的这篇就够了,因为我就是参考他们的,嘻嘻.

iOS开发系列--并行开发其实很容易

概览 大家都知道,在开发过程中应该尽可能减少用户等待时间,让程序尽可能快的完成运算.可是无论是哪种语言开发的程序最终往往转换成汇编语言进而解释成机器码来执行.但是机器码是按顺序执行的,一个复杂的多步操作只能一步步按顺序逐个执行.改变这种状况可以从两个角度出发:对于单核处理器,可以将多个步骤放到不同的线程,这样一来用户完成UI操作后其他后续任务在其他线程中,当CPU空闲时会继续执行,而此时对于用户而言可以继续进行其他操作:对于多核处理器,如果用户在UI线程中完成某个操作之后,其他后续操作在别的线程

iOS开发系列--通知与消息机制

概述 在多数移动应用中任何时候都只能有一个应用程序处于活跃状态,如果其他应用此刻发生了一些用户感兴趣的那么通过通知机制就可以告诉用户此时发生的事情.iOS中通知机制又叫消息机制,其包括两类:一类是本地通知:另一类是推送通知,也叫远程通知.两种通知在iOS中的表现一致,可以通过横幅或者弹出提醒两种形式告诉用户,并且点击通知可以会打开应用程序,但是实现原理却完全不同.今天就和大家一块去看一下如何在iOS中实现这两种机制,并且在文章后面会补充通知中心的内容避免初学者对两种概念的混淆. 本地通知 推送通

iOS开发之多线程

1.多线程概念 进程 正在进行中的程序被称为进程,负责程序运行的内存分配.每一个进程都有自己独立的虚拟内存空间.  线程 线程是进程中一个独立的执行路径(控制单元) 一个进程中至少包含一条线程,即主线程 可以将耗时的执行路径(如:网络请求)放在其他线程中执行 创建线程的目的就是为了开启一条新的执行路径,运行指定的代码,与主线程中的代码实现同时运行.   栈区:主线程栈区的1M,非常非常宝贵.一个进程,至少有一个线程(主线程),不能杀掉一个线程!但是可以暂停.休眠. 2.多任务系统调度示意图  

iOS开发网络篇—XML介绍

一.XML简单介绍 XML:全称是Extensible Markup Language,译作"可扩展标记语言" 跟JSON一样,也是常用的一种用于交互的数据格式,一般也叫XML文档(XML Document)   XML举例 <videos>     <video name="小黄人 第01部" length="30" />     <video name="小黄人 第02部" length=&q

《iOS开发指南》正式出版-源码-样章-目录,欢迎大家提出宝贵意见

我的最新作品:<iOS开发指南-从0基础到AppStore上线>正式出版了 iOS架构设计.iOS性能优化.iOS测试驱动.iOS调试.iOS团队协作版本控制......应有尽有 京东销售地址:http://item.jd.com/11288969.html 当当销售地址:http://product.dangdang.com/product.aspx?product_id=23290237 亚马逊销售:地址太长了,直接连接了 图灵社区在线阅读,购买地址:http://www.ituring.

iOS开发系列--通讯录、蓝牙、内购、GameCenter、iCloud、Passbook系统服务开发汇总

iOS开发过程中有时候难免会使用iOS内置的一些应用软件和服务,例如QQ通讯录.微信电话本会使用iOS的通讯录,一些第三方软件会在应用内发送短信等.今天将和大家一起学习如何使用系统应用.使用系统服务: 调用系统应用 使用系统服务 短信与邮件 通讯录 蓝牙 社交 Game Center 应用内购买 iCloud Passbook 目 录 系统应用 在开发某些应用时可能希望能够调用iOS系统内置的电话.短信.邮件.浏览器应用,此时你可以直接使用UIApplication的OpenURL:方法指定特定