Grand Central Dispatch をテストするための小さなテスト プロジェクトを作成しました。シリアル キューを使用する必要があります。バックグラウンド タスクの実行中に、スレッドを完全に中断、再開、またはキャンセルする必要があります。そして: 作成されたキューが既に実行されているかどうかはどうすればわかりますか? (その後、再起動する必要があります)。
マルチスレッドを使用するのは初めてなので、正しく使用できているかどうかのヒントを得ることができれば本当にうれしいです. 私はそのようなものを見つけられなかったので、私のコードをチェックしていただければ幸いです. オブジェクトを正しく解放しますか? さらなる改善はありますか?
あなたの助けと時間をありがとう。
コードまたはサンプル プロジェクトへのリンクを次に示します。
ViewController.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
Queue.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