To address this issue, I think of two solutions: the first is to determine whether it has been initialized before performing these operations and, if not initialized, to use an array queue to store the operation parameters and the methods invoked, wait for the initialization to be completed, and then detect the saved operations in the array queue to call and empty the queue. But there is a problem in this way is that the parameters passed in the operation and invoke method references are required to maintain their own, which is undoubtedly to bring themselves a certain amount of work and risk, a little careless may lead to memory leaks.
Therefore, the second solution is to use the serial queue combined with the signal volume to control the execution of the operation. The idea of this scenario is to create a serial queue that is used to perform all operations. But the first team was a waiting signal operation. The initial value of this signal is 0 until the initialization operation is completed before a signal is sent to notify the operation. Therefore, the queue is blocked until the initialization has been completed. So when an operation enters the queue, it executes immediately, but it needs to wait until the initialization signal comes along before it starts executing.
To verify this idea, I created an application project that defined the operation queue _quque and semaphore _sema in Viewcontroller, as follows:
@interface Viewcontroller:uiviewcontroller
{
@private
dispatch_queue_t _queue;
dispatch_semaphore_t _sema;
}
@end
Create an action queue when initializing
-(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;
}
There are three buttons defined in the Viewcontroller, dosomething, Signal, wait, respectively. Where DoSomething is the action performed. Signal can perform an operation for notification blocking queues. Wait to block the current queue.
-(void) viewdidload
{
[Super Viewdidload];
Do no 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);
});
}
After running, click Wait to let the queue block, and then no matter how to click DoSomething will not have log information to display, until the click Signal, the dosomething will print out the information.
This solution can be seen to be feasible and easier to operate.