如何通过q​​ueue / NSThread为UI设计处理并发,iOS开发

时间:2013-05-12 08:22:37

标签: ios queue nsthread

我想要实现的目标很简单,从最初的思考开始。我终于发现很难处理。

我想将表格视图作为选择列表,用户选择一个单元格并将单元格字符串作为选定字符串发送到上一个视图,简单呵呵

先看两张照片

select housing, then push to the next view

select one cell in this view

困扰我的是:

我想提供(至少)两个按钮,左边一个是由导航控制器自动生成的后退按钮,右边是用于编辑的按钮。并且导航控制器默认有两个按钮(据我所知)。因此没有“完成”按钮的位置,用户可以点击然后确认并弹出到上一个视图。 因此,当用户点击一个单元格,例如“穿着”时,我希望以下内容发生,自动且直观地为用户提供:

  1. 用户可以看到“住房”单元格未标记
  2. 然后用户可以看到“穿着”单元格已标记
  3. 然后经过一段时间间隔(比如0.2秒),弹出上一个视图并更新选择,自动
  4. 起初我认为这很容易,但绝对不是。这是我的代码,但是工作有线

        - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {

    dispatch_queue_t queue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH,0ul); dispatch_async(queue, ^{ //unmark previous cell if (selectedIndexPath!=nil) { [[self.tableView cellForRowAtIndexPath:selectedIndexPath]setAccessoryType:UITableViewCellAccessoryNone]; } selectedIndexPath=indexPath; //get the selected cell to mark UITableViewCell *cell=[self.tableView cellForRowAtIndexPath:indexPath]; [cell setAccessoryType:UITableViewCellAccessoryCheckmark]; dispatch_sync(dispatch_get_main_queue(), ^{ //wait a little [NSThread sleepForTimeInterval:0.2]; //return to previous view NSLog(@"here........."); if ([objectToUpdateCategory respondsToSelector:@selector(updateCategoryTo:withSelectedIndexPath:)]) { NSLog(@"sending.......... update info"); [objectToUpdateCategory updateCategoryTo:cell.textLabel.text withSelectedIndexPath:selectedIndexPath]; NSLog(@"sent update info"); } [self.navigationController popViewControllerAnimated:YES]; }); });

    棘手的是,如果我把 [self.navigationController popViewControllerAnimated:YES] ;到最后,视图将不会直观地更新取消标记并标记步骤并立即返回上一个视图。起初,当我不考虑unmark事物时,代码中的“队列”内容可以在弹出之前在视觉上执行标记步骤,但有时不起作用。我不知道我的代码是否正确,实际上我不是我非常了解这个来自苹果的队列技术。但是我很确定它与NSThread /队列有关,或者处理并发性。我已经检查了Apple文档一整天,没有找到直接的答案。

    希望有人可以帮助我,提前谢谢:)

2 个答案:

答案 0 :(得分:1)

“经过一段时间间隔(比如0.2秒)后,弹出上一个视图”,使用performSelector:withObject:afterDelay:方法或其中一个变体,例如:

[self performSelector:@selector(delayedPop) withObject:nil afterDelay:0.2];

并将popViewControllerAnimated放入delayedPop方法,例如:

-(void)delayedPop{
    [self.navigationController popViewControllerAnimated:YES];
}

答案 1 :(得分:0)

首先,正如我在评论中所写,您不应该在后台线程上更新UI。这将导致很多问题,包括UI没有立即更新。在您的情况下,您根本不需要使用dispatch_async或dispatch_sync。我要做的是在视图控制器中创建一个显示类别表视图的属性:

@property (nonatomic, weak) id<CategoryControllerDelegate> delegate;

当您在堆栈上按类别控制器时,您将费用控制器设置为代理。然后,当用户在类别控制器中进行选择时,您可以调用委托上的方法(在协议中定义),例如代码示例中的方法:

@protocol CategoryControllerDelegate<NSObject>
@optional
- (void) updateCategoryTo: (NSString*) category withSelectedIndexPath: (NSIndexPath*) path;
@end

之后,将当前视图控制器从堆栈中弹出。