nod*_*nja 14 multithreading cocoa-touch background objective-c nsthread
我正在尝试使用我在某处下载的类中的方法.程序执行继续时,该方法在后台执行.在此方法完成之前,我不想让程序继续执行.我怎么做?
jps*_*ain 39
这是使用GCD执行此操作的另一种方法:
- (void)main
{
[self doStuffInOperations];
}
- (void)doStuffInGCD
{
dispatch_group_t d_group = dispatch_group_create();
dispatch_queue_t bg_queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_async(d_group, bg_queue, ^{
[self doSomething:@"a"];
});
dispatch_group_async(d_group, bg_queue, ^{
[self doSomething:@"b"];
});
dispatch_group_async(d_group, bg_queue, ^{
[self doSomething:@"c"];
});
// you can do this to synchronously wait on the current thread:
dispatch_group_wait(d_group, DISPATCH_TIME_FOREVER);
dispatch_release(d_group);
NSLog(@"All background tasks are done!!");
// **** OR ****
// this if you just want something to happen after those are all done:
dispatch_group_notify(d_group, dispatch_get_main_queue(), ^{
dispatch_release(d_group);
NSLog(@"All background tasks are done!!");
});
}
- (void)doSomething:(id)arg
{
// do whatever you want with the arg here
}
Run Code Online (Sandbox Code Playgroud)
使用NSOperationQueue,就像这样
(从内存中原谅任何小错误 - 你会得到基本的想法):
// ivars
NSOperationQueue *opQueue = [[NSOperationQueue alloc] init];
// count can be anything you like
[opQueue setMaxConcurrentOperationCount:5];
- (void)main
{
[self doStuffInOperations];
}
// method
- (void)doStuffInOperations
{
// do parallel task A
[opQueue addOperation:[[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(doSomething:) object:@"a"] autorelease]];
// do parallel task B
[opQueue addOperation:[[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(doSomething:) object:@"b"] autorelease]];
// do parallel task C
[opQueue addOperation:[[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(doSomething:) object:@"c"] autorelease]];
[opQueue waitUntilAllOperationsHaveFinished];
// now, do stuff that requires A, B, and C to be finished, and they should be finished much faster because they are in parallel.
}
- (void)doSomething:(id)arg
{
// do whatever you want with the arg here
// (which is in the background,
// because all NSOperations added to NSOperationQueues are.)
}
Run Code Online (Sandbox Code Playgroud)
我的第一个倾向是不做你的建议.我之前使用的技术是为线程提供一个选择器,用于原始对象(位于主线程上)中的方法.当第二个线程启动时,主线程继续执行,但在显示屏上显示某种忙碌指示符.这允许用户交互在需要时继续.
当第二个线程结束时,就在它关闭之前,它会调用主线程上的选择器.然后,选择器引用的方法从显示中删除忙指示符并告诉主线程更新,获取第二个线程生成的任何数据.
我成功地将这个用于访问Web服务的应用程序(在第二个线程上),然后在返回数据后更新显示而不锁定它.这使用户体验更好.
对于这种情况,我通常使用NSCondition类.
//this method executes in main thread/queue
- (void)waitForJob
{
id __weak selfWeak = self;
NSCondition *waitHandle = [NSCondition new];
[waitHandle lock];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
[selfWeak doSomethingLongtime];
[waitHandle signal];
});
//waiting for background thread finished
[waitHandle waitUntilDate:[NSDate dateWithTimeIntervalSinceNow:60]];
}
Run Code Online (Sandbox Code Playgroud)
我建议在您自己的方法中结束对类方法的调用,并在完成后设置一个布尔值。例如:
BOOL isThreadRunning = NO;
- (void)beginThread {
isThreadRunning = YES;
[self performSelectorInBackground:@selector(backgroundThread) withObject:nil];
}
- (void)backgroundThread {
[myClass doLongTask];
// Done!
isThreadRunning = NO;
}
- (void)waitForThread {
if (! isThreadRunning) {
// Thread completed
[self doSomething];
}
}
Run Code Online (Sandbox Code Playgroud)
您希望如何处理等待取决于您:也许使用 [NSThread sleepForTimeInterval:1] 或类似的轮询,或者每个运行循环向自己发送一条消息。
| 归档时间: |
|
| 查看次数: |
30360 次 |
| 最近记录: |