等待线程目标C中的值更改

时间:2018-12-15 14:11:02

标签: ios objective-c multithreading nsthread

我在目标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的值并返回我正在使用的值

  

可可粉

我正在将值返回到另一个应用程序

任何人都可以帮忙。

谢谢

1 个答案:

答案 0 :(得分:3)

例如,您在这里需要使用semaphore。如果仅提供您此处提供的内容,那么完成后台运行方法的块是最好的方法。 请参阅下面的选项2

无论哪种方式,为什么要让父线程(分派新线程的线程)等待另一个线程?如果父线程正在等待,它将被锁定,直到派遣线程完成为止(根据您的要求)。这种情况是多余的,因为调度另一个线程的整个目的是使父线程可以继续执行其他操作。除非父线程当然需要等待多个线程,否则将其锁定是有意义的。

话虽如此,最好只是让调度线程/父线程执行您要调度到另一个线程的处理。鉴于您提供的详细信息,我只是在说这句话。

  • 选项1使用信号灯

使用信号量锁定和解锁父线程

-(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
}

但是,正如我之前提到的,这种情况似乎是多余的,因为父线程等待(因此无法使用)子线程;为什么它不能自己完成工作...


  • 选项2使用完成块(可参考)

使用传递给子线程的完成块。这允许父线程继续。如果它是主线程,则它对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