【问题标题】:How do I pause 10 seconds to send input out with out losing the data iOS如何暂停 10 秒以发送输入而不会丢失数据 iOS
【发布时间】:2014-08-07 20:43:01
【问题描述】:

我的一个程序中有一个按钮,当您单击它时,它会向 UDP 数据包发送一个字符串。字符串需要在输入后 10 被发送出去。我遇到的问题是,当我使用 NSTimer 或 [self performSelector:@selector(sendUDPMessage) withObject:nil afterDelay:2.0f];最后一个字符串是发送的内容,而不是预期的输入。

当调用 sendUDPMessage 函数时,我还尝试了几种不同类型的循环来发送数组中的下一个元素,但我没有运气。

到目前为止,这是我的代码:

- (IBAction)RecordButton:(UIButton *)sender {

NSDateFormatter *clockFormat = [[NSDateFormatter alloc] init];
[clockFormat setDateFormat:@"kk:mm:ss:SSS"];

NSString *myT = [clockFormat stringFromDate:[NSDate date]];
NSString *Str = display.text;

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

//[_updArray addObject:_dataString];

[self performSelector:@selector(sendUDPMessage) withObject:nil afterDelay:2.0f];

[_tableView reloadData];

我在 perform for 选择器中调用的函数是:

-(void)sendUDPMessage {

    data = [_dataString dataUsingEncoding:NSUTF8StringEncoding];
    [udpSocket sendData:data toHost:ipSaved port:portSaved withTimeout:-1.0 tag:0];

}

我明白为什么它不起作用。这是因为 performselector 暂停发送它而不是字符串本身。我尝试使用 sendUDPMessage 保存字符串,但发生了同样的问题。

【问题讨论】:

  • 为什么有人会否决这个问题?问题很清楚。它显示了相关代码并解释了问题。你还想要什么?

标签: ios objective-c nstimer performselector


【解决方案1】:

将所需数据作为参数传递,而不是依赖于实例变量的当前值:

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

然后调用它:

[self performSelector:@selector(sendUDPMessage:) withObject:[_dataString copy] afterDelay:2.0f];

稍微扩展一下:

没有理由对数据字符串使用 ivar。你可以这样做:

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

[self performSelector:@selector(sendUDPMessage:) withObject:dataString afterDelay:2.0f];

正如 Martin 所指出的,使用 GCD 更加容易。你可以去掉senUDPMessage:方法,直接使用dispatch_after

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

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    data = [dataString dataUsingEncoding:NSUTF8StringEncoding];
    [udpSocket sendData:data toHost:ipSaved port:portSaved withTimeout:-1.0 tag:0];
});

您甚至可能希望在后台线程上调度。

【讨论】:

  • 或者,使用dispatch_after()
  • @MartinR 使用 dispatch_after 如果块刚刚访问了 ivar,则与 OP 的代码有相同的问题。虽然我更喜欢使用 GCD 而不是各种 performSelector 方法,但任何一种解决方案都需要确保它使用正确的值。
  • 当然,在这种情况下,消息可能是局部变量,不需要 ivar。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-10
  • 1970-01-01
  • 2018-01-26
  • 2011-04-06
  • 1970-01-01
相关资源
最近更新 更多