Synchronize operations using operation queues and semaphores

Source: Internet
Author: User

Recently, I encountered a problem during iOS development: some operations must be allowed after an initialization operation. However, the execution time of these operations may be faster than the initialization operation. If you do not wait for the initialization operation to be executed, these operations will be lost.

To solve this problem, I have come up with two solutions: the first is to determine whether initialization has been performed before performing these operations, if Initialization is not performed, use an array queue to store operation parameters and call methods. Wait until the initialization is complete and check the stored operations in the array queue for calling and clearing the queue. However, a problem with this method is that the parameters passed in the operation and call method references must be maintained by yourself, which undoubtedly brings a certain amount of work and risks to you, A slight carelessness may cause memory leakage.

Therefore, the second solution is to use the serial queue and semaphore to control the operation execution. The idea of this solution is to create a serial queue for all operations. However, the first operation to join the queue is a waiting signal operation. The initial value of this signal is 0, and a signal will not be sent until the initialization operation is complete to notify this operation. Therefore, the queue is always in the blocking state when Initialization is not complete. Therefore, operations will be executed immediately when they enter the queue, but they will not be executed until the initialization signal comes over.

To verify this idea, I created an application project and defined the operation queue _ quque and semaphore _ sema in ViewController, as follows:

 
 
  1. @interface ViewController : UIViewController   
  2.  
  3.  {   
  4.  
  5.  @private  
  6.  
  7.      dispatch_queue_t _queue;   
  8.  
  9.      dispatch_semaphore_t _sema;   
  10.  
  11.  }   
  12.     
  13.  
  14. @end  

Create operation queue during initialization

 
 
  1. - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil   
  2.  
  3.  {   
  4.  
  5.      if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])   
  6.  
  7.      {   
  8.  
  9.          _queue = dispatch_queue_create("cn.vimfung.demo", DISPATCH_QUEUE_SERIAL);   
  10.  
  11.     }   
  12.  
  13.          
  14.  
  15.      return self;   
  16.  
  17.  }  

Three buttons are defined in ViewController: DoSomething, Signal, and Wait. DoSomething indicates the executed operation. Signal can perform operations for the notification blocking queue. Wait blocks the current queue.

 
 
  1. - (void)viewDidLoad   
  2.  
  3.  {   
  4.  
  5.      [super viewDidLoad];   
  6.  
  7.      // Do any additional setup after loading the view, typically from a nib.   
  8.  
  9.          
  10.  
  11.      UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];   
  12.  
  13.      [btn setTitle:@"DoSomething" forState:UIControlStateNormal];   
  14.  
  15.      [btn sizeToFit];   
  16.  
  17.      [btn addTarget:self action:@selector(doSomethingHandler:) forControlEvents:UIControlEventTouchUpInside];   
  18.  
  19.      [self.view addSubview:btn];   
  20.  
  21.          
  22.  
  23.      UIButton *btn1 = [UIButton buttonWithType:UIButtonTypeRoundedRect];   
  24.  
  25.      [btn1 setTitle:@"Signal" forState:UIControlStateNormal];   
  26.  
  27.      [btn1 sizeToFit];   
  28.  
  29.      [btn1 addTarget:self action:@selector(signalHanlder:) forControlEvents:UIControlEventTouchUpInside];   
  30.  
  31.      btn1.frame = CGRectMake(0.0, 50.0, btn1.frame.size.width, btn1.frame.size.height);   
  32.  
  33.      [self.view addSubview:btn1];   
  34.  
  35.          
  36.  
  37.      UIButton *btn2 = [UIButton buttonWithType:UIButtonTypeRoundedRect];   
  38.  
  39.      [btn2 setTitle:@"Wait" forState:UIControlStateNormal];   
  40.  
  41.      [btn2 sizeToFit];   
  42.  
  43.      [btn2 addTarget:self action:@selector(waitHanlder:) forControlEvents:UIControlEventTouchUpInside];   
  44.  
  45.      btn2.frame = CGRectMake(0.0, 100.0, btn2.frame.size.width, btn2.frame.size.height);   
  46.  
  47.      [self.view addSubview:btn2];   
  48.  
  49.  }   
  50.  
  51.      
  52.  
  53.  - (void)doSomethingHandler:(id)sender   
  54.  
  55.  {   
  56.  
  57.      dispatch_async(_queue, ^{   
  58.  
  59.         NSLog(@"do something");   
  60.  
  61.      });   
  62.  
  63.  }   
  64.  
  65.      
  66.  
  67.  - (void)signalHanlder:(id)sender   
  68.  
  69.  {   
  70.  
  71.      dispatch_semaphore_signal(_sema);   
  72.  
  73.  }   
  74.  
  75.      
  76.  
  77.  - (void)waitHanlder:(id)sender   
  78.  
  79.  {   
  80.  
  81.      if (_sema)   
  82.  
  83.     {   
  84.  
  85.          dispatch_release(_sema);   
  86.  
  87.      }   
  88.  
  89.     _sema = dispatch_semaphore_create(0);   
  90.  
  91.     dispatch_async(_queue, ^{   
  92.  
  93.          dispatch_semaphore_wait(_sema, DISPATCH_TIME_FOREVER);   
  94.  
  95.      });   
  96.  
  97.  } 

After running, click Wait to block the queue. Then, no log information is displayed when you click DoSomething. After you click Signal, the previously clicked DoSomething will print the information one by one.

This solution is feasible and easier to operate.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.