【问题标题】:Returning to background thread from UIAlertViewDelegate callback从 UIAlertViewDelegate 回调返回后台线程
【发布时间】:2012-10-09 13:52:12
【问题描述】:

我有一个从存档中读取的导入序列,解压缩包含的文件并为每个文件创建相应的核心数据实体。整个过程发生在后台,并且为每个线程等创建了一个单独的上下文,所以一切正常。

事实证明,这个特定导入序列的一个理想特性是我们允许任何输入文件受密码保护(其中有几个包含在存档中)所以我需要检查文件是否受密码保护在这种情况下,系统将提示用户通过UIAlertView 输入密码。

这是我的问题开始的地方。

我按我应该将UIAlertView 提示发送到主线程,将我的Importer object 分配为delegate 并等待用户输入。

当用户输入密码并点击 OK/Cancel 时,委托回调仍在主线程上,因此我无法在没有大量工作的情况下再操作相应的核心数据实体(即存储对托管对象 ID 的引用等,创建新的上下文等)。

我的问题:

是否可以返回正在执行导入过程的原始后台线程?我该怎么办?

谢谢, 罗格

【问题讨论】:

  • 您的导入器能否使用[NSThread currentThread] 保留对其线程的引用,然后在委托回调中使用performSelector:onThread:withObject:waitUntilDone: 将密码传回导入器的线程?
  • 在开始处理文件之前,我会检查所有文件的密码,并预先询问密码。这样,如果我正在进行长时间的导入,我可以启动它然后走开,一个小时后不回来期待它完成,然后发现它在第三个文件中等待我输入密码....

标签: objective-c ios core-data grand-central-dispatch


【解决方案1】:

我会尝试使用dispatch semaphore。将其保存在实例变量中。

@interface MyClass ()
{
    dispatch_semaphore_t dsema;
}
@end

然后,在后台线程方法中:

// this is the background thread where you are processing the archive files
- (void)processArchives
{
    ...
    self.dsema = dispatch_semaphore_create(0);
    dispatch_async(dispatch_get_main_queue(), ^{
        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle: @"Title"
                                                                ...
                                                           delegate: self
                                                                ...
        ];
        [alertView show];
    });

    dispatch_semaphore_wait(self.dsema, DISPATCH_TIME_FOREVER);
    // --> when you get here, the user has responded to the UIAlertView <--

    dispatch_release(self.dsema);
    ...
}

UIAlertView 将调用此委托方法:

// this is running on the main queue, as a method on the alert view delegate
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    // do stuff with alertView
    if (buttonIndex == [alertView firstOtherButtonIndex]) {
        ...
        // when you get the reply that should unblock the background thread, unblock the other thread:
        dispatch_semaphore_signal(self.dsema);
        ...
    }
}

【讨论】:

  • 谢谢,这非常好,我也学到了一些新东西:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-10-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-25
  • 1970-01-01
相关资源
最近更新 更多