【问题标题】:How do I stop a perform selector when i delete a row from a table view?当我从表视图中删除一行时,如何停止执行选择器?
【发布时间】:2014-08-14 16:54:44
【问题描述】:

我有一个应用程序,当您单击按钮时会发送 UDP 消息。然后我给他们 10 秒钟的时间来改变他们是否要发送消息的想法。我用:

[self performSelector:@selector(sendMessage:) withObject:_dataString afterDelay:10.0f];

这是按钮按下的代码:

- (IBAction)RecordButton:(UIButton *)sender {
    NSString *Str = display.text;
    NSDateFormatter *clockFormat = [[NSDateFormatter alloc] init];
    [clockFormat setDateFormat:@"kk:mm:ss:SSS"];

    NSString *myT = [clockFormat stringFromDate:[NSDate date]];

    _dataString = [NSString stringWithFormat:@"0, %@, %@, \"%@\"", Str, Str, myT];

    [self performSelector:@selector(sendMessage:) withObject:_dataString afterDelay:10.0f];

    [_tableView reloadData];
}

- (void)sendMessage:(NSString *)message {
    NSData *data = [message dataUsingEncoding:NSUTF8StringEncoding];
    [udpSocket sendData:data toHost:ipSaved port:portSaved withTimeout:-1.0 tag:0];
}

我有一个可编辑的表格视图,当我删除一个表格视图单元格及其中的数据时,我想阻止单元格中的任何数据在 10 秒的时间限制内发送。

我知道有 [NSObject cancelPreviousPerformRequestsWithTarget:yourTarget selector:aSelector object: anArgument]; ,但在删除表格视图单元格和其中的核心数据后,我无法弄清楚如何阻止消息发送。

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{
    if (editingStyle == UITableViewCellEditingStyleDelete)
    {
        [tableView beginUpdates];

        [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];

        [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(sendMessage:) object:_dataString];

        [self.managedObjectContext deleteObject:[self.getRaceRecords objectAtIndex:indexPath.row]];
        NSError *error;
        if (![self.managedObjectContext save:&error]) {
            NSLog(@"did not save: %@", [error localizedDescription]);
        }
    }
}

【问题讨论】:

  • 为什么要删除您最初为commitEditingStyle: 方法发布的代码?显示您如何尝试致电cancelPreviousPerformRequestsWithTarget:...
  • 我同意@rmaddy,您在问题中发布的代码 sn-p 很有用。
  • 您似乎在使用实例变量_dataString 来保存将与cancelPrevious... 一起使用的消息。问题是该字符串将被下一次调用RecordButton 覆盖。因此,如果您将多条消息排队,删除任何一行都会取消排队的最后一条消息。
  • 为什么不直接配置一个NSTimer 在10 秒后调用你的sendMessage: 方法呢?如果用户在 10 秒结束前改变主意,您可以让计时器失效。

标签: ios objective-c uitableview performselector


【解决方案1】:

(假设一切都在主线程上运行,因此不存在任何同步问题。)这是我要做的:

  • 为每条消息分配一个唯一的序列号
  • 在创建消息时将序列号添加到NSSet
  • 从 NSSet 中删除序列号

    a) 消息被取消,或
    b) 消息已发送

  • sendMessage方法中,验证序列号在 发送消息前的NSSet

【讨论】:

    【解决方案2】:

    你应该看看 NSOperationQueue 并创建一个 NSOperation 的子类。 NSOperations 可以取消——你必须编写一些代码来完成它,但它相当容易。 NSOperations 意味着被取消。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-07-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多