我在目标C中有一个线程调用,并且我希望该线程结束后我想返回一个值;该值将在线程内更改 因此,除非胎面终止,否则该方法不得返回该值
这是我使用的代码:
[NSThread detachNewThreadSelector:@selector(CheckBeforePrint2) toTarget:self withObject:nil];
这是我的完整代码
- (NSString *) getStatusPrinter:(NSString *) printerSerialNumber
{
self.printerSN = printerSerialNumber;
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSString *Result = @"-1";
[NSThread sleepForTimeInterval:2.0f];
[NSThread detachNewThreadSelector:@selector(CheckBeforePrint) toTarget:self withObject:Result];
[pool release];
return Result;
}
现在我要等待Result的值并返回我正在使用的值
可可粉
我正在将值返回到另一个应用程序
任何人都可以帮忙。
谢谢
答案 0 :(得分:3)
例如,您在这里需要使用semaphore
。如果仅提供您此处提供的内容,那么完成后台运行方法的块是最好的方法。 请参阅下面的选项2
无论哪种方式,为什么要让父线程(分派新线程的线程)等待另一个线程?如果父线程正在等待,它将被锁定,直到派遣线程完成为止(根据您的要求)。这种情况是多余的,因为调度另一个线程的整个目的是使父线程可以继续执行其他操作。除非父线程当然需要等待多个线程,否则将其锁定是有意义的。
话虽如此,最好只是让调度线程/父线程执行您要调度到另一个线程的处理。鉴于您提供的详细信息,我只是在说这句话。
使用信号量锁定和解锁父线程
-(void)getStatusPrinter()
{
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
[NSThread detachNewThreadSelector:@selector(checkBeforePrint2) toTarget:self withObject: semaphore];
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
[self print]; // this will run after semaphore is unlocked
}
-(void)checkBeforePrint2:(dispatch_semaphore_t)sem
{
//this is within child thread
//do some processing,
dispatch_semaphore_signal(sem);//unlock semaphore
}
但是,正如我之前提到的,这种情况似乎是多余的,因为父线程等待(因此无法使用)子线程;为什么它不能自己完成工作...
使用传递给子线程的完成块。这允许父线程继续。如果它是主线程,则它对UI而言仍然是免费的。
-(void)getStatusPrinter()
{
[self checkBeforePrint2WithCompletion: ^{
[self print];
}];
//continue with more stuff
}
-(void)checkBeforePrint2WithCompletion:(void (^ __nullable)(void))completion
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//do something before executing completion code
if(completion){
completion();
}
});
}
免责声明:此代码中可能有错别字,因为它不是在编辑器/ IDE中编写的。请发表评论。
好的,因为您说过需要将结果返回到另一个应用程序,所以这意味着getStatusPrinter
处的入口线程在分派新线程后将不允许返回。如果确实需要为CheckBeforePrint
创建一个新线程,则输入线程必须等待。这对我来说毫无意义。您只需在入口线程上运行所有内容即可。
如果您正在使用openURL:options:completionHandler:
,则输入线程无需等待。 result
的值可以在完成代码块内传递回去。
请参考带有完成句柄的openURL上的Apple's documentation