我刚刚建立了一个小型测试项目来测试 Grand Central Dispatch。我需要使用串行队列。在运行后台任务时,我需要完全暂停、恢复或取消线程。并且:我如何知道创建的队列是否已经在运行?(然后我必须重新启动它)。
这是我第一次使用多线程,因此如果我使用正确的话,得到一些提示会非常好。我没有找到类似的东西,如果你能检查我的代码,那就太酷了。我释放对象对吗?有没有进一步的改进?
非常感谢您的帮助和时间。
这是代码或示例项目的链接。
视图控制器.m
#import "ViewController.h"
#import "SVProgressHUD.h"
#import "Queue.h"
@interface ViewController (){
Queue* queue;
}
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
queue = [[Queue alloc] init];
UIButton* startbutton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[startbutton setTitle:@"Start Queue" forState:UIControlStateNormal];
[startbutton addTarget:self action:@selector(startQueueButton:) forControlEvents:UIControlEventTouchUpInside];
[startbutton setFrame:CGRectMake(100, 200, 100, 70)];
[self.view addSubview:startbutton];
UIButton* suspendbutton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[suspendbutton setTitle:@"Stop Queue" forState:UIControlStateNormal];
[suspendbutton addTarget:self action:@selector(suspendQueueButton:) forControlEvents:UIControlEventTouchUpInside];
[suspendbutton setFrame:CGRectMake(250, 200, 100, 70)];
[self.view addSubview:suspendbutton];
UIButton* resumebutton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[resumebutton setTitle:@"Resume Queue" forState:UIControlStateNormal];
[resumebutton addTarget:self action:@selector(resumeQueueButton:) forControlEvents:UIControlEventTouchUpInside];
[resumebutton setFrame:CGRectMake(400, 200, 170, 70)];
[self.view addSubview:resumebutton];
UIButton* cancelbutton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[cancelbutton setTitle:@"Cancel Queue" forState:UIControlStateNormal];
[cancelbutton addTarget:self action:@selector(cancelQueueButton:) forControlEvents:UIControlEventTouchUpInside];
[cancelbutton setFrame:CGRectMake(600, 200, 170, 70)];
[self.view addSubview:cancelbutton];
}
-(void) startQueueButton:(UIButton*) button{
NSLog(@"---> startQueueButton");
[queue start];
}
-(void) suspendQueueButton:(UIButton*) button{
NSLog(@"---> suspendQueueButton");
[queue suspend];
}
-(void) resumeQueueButton:(UIButton*) button{
NSLog(@"---> resumeQueueButton");
[queue resume];
}
-(void) cancelQueueButton:(UIButton*) button{
NSLog(@"---> cancelQueueButton");
[queue cancel];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
@end
队列.m
#import "Queue.h"
#import "SVProgressHUD.h"
@interface Queue (){
dispatch_queue_t queue;
}
@end
@implementation Queue
-(void) start{
NSLog(@"Queue - start");
int count = 1000;
// SERIAL QUEUE ======================================
// =======================================================================
queue = dispatch_queue_create("com.jf.TestQueue", NULL);
[SVProgressHUD showWithStatus:@"Rendering..."];
for(int i = 0; i < count; i++)
{
dispatch_async(queue, ^{
NSLog(@"--> ASYNC %d", i);
// rendering complete, get back to main queue
dispatch_async(dispatch_get_main_queue(), ^
{
NSLog(@"--> Image rendered: %d", i);
if (i == count-1) {
NSLog(@"EndRenderingQueue");
[SVProgressHUD dismiss];
}
});
});
}
dispatch_release(queue); // even under ARC we have to release it
}
-(void) suspend{
NSLog(@"Queue - suspend");
if (queue) {
NSLog(@"___suspend");
dispatch_suspend(queue);
}
}
-(void) resume{
NSLog(@"Queue - resume");
if (queue) {
dispatch_resume(queue);
}
}
-(void) cancel{
NSLog(@"Queue - cancel");
if (queue) {
dispatch_suspend(queue);
//dispatch_release(queue); // if it´s uncommented, it crashes. How to release it securely?
queue = nil;
[SVProgressHUD dismiss];
}
}
@end