覆盖调度命令
Overwrite dispatch command
我有一个发送错误消息的函数 (sendError
)。然后在 5 秒后像这样删除它:
-(void)sendError:(NSString*)message{
_errorMessage.stringValue = message;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
_errorMessage.stringValue = @"";
});
}
问题是,如果按钮是 运行 一次,然后在 3 秒后再次出现,第二次是 运行,消息将在 2 秒后而不是 5 秒后删除。
我该如何取消之前的调度并编写一个新调度(覆盖)。
有几种方法可以做到这一点。首先,您可以停止使用 GCD 并返回到更早的机制,-performSelector:withObject:afterDelay:
。这里的优点是有一种方法 +cancelPreviousPerformRequestsWithTarget:selector:object:
可以取消 still-pending 执行请求。
-(void)sendError:(NSString*)message{
_errorMessage.stringValue = message;
[NSObject cancelPreviousPerformRequestsWithTarget:_errorMessage selector:@selector(setStringValue:) object:@""];
[_errorMessage performSelector:@selector(setStringValue:) withObject:@"" afterDelay:5];
}
如果您想继续使用 GCD,则需要自行跟踪取消。一种方法是保持 "generation" 计数。因此,假设存在一个名为 _errorGeneration
.
的 NSUInteger
实例变量
-(void)sendError:(NSString*)message{
_errorMessage.stringValue = message;
_errorGeneration++;
NSUInteger capturedGeneration = _errorGeneration;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
if (_errorGeneration == capturedGeneration)
_errorMessage.stringValue = @"";
});
}
基本上,您不会取消已分派的任务(因为您不能),但是如果它已过时,您可以让它什么也不做。
我有一个发送错误消息的函数 (sendError
)。然后在 5 秒后像这样删除它:
-(void)sendError:(NSString*)message{
_errorMessage.stringValue = message;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
_errorMessage.stringValue = @"";
});
}
问题是,如果按钮是 运行 一次,然后在 3 秒后再次出现,第二次是 运行,消息将在 2 秒后而不是 5 秒后删除。
我该如何取消之前的调度并编写一个新调度(覆盖)。
有几种方法可以做到这一点。首先,您可以停止使用 GCD 并返回到更早的机制,-performSelector:withObject:afterDelay:
。这里的优点是有一种方法 +cancelPreviousPerformRequestsWithTarget:selector:object:
可以取消 still-pending 执行请求。
-(void)sendError:(NSString*)message{
_errorMessage.stringValue = message;
[NSObject cancelPreviousPerformRequestsWithTarget:_errorMessage selector:@selector(setStringValue:) object:@""];
[_errorMessage performSelector:@selector(setStringValue:) withObject:@"" afterDelay:5];
}
如果您想继续使用 GCD,则需要自行跟踪取消。一种方法是保持 "generation" 计数。因此,假设存在一个名为 _errorGeneration
.
NSUInteger
实例变量
-(void)sendError:(NSString*)message{
_errorMessage.stringValue = message;
_errorGeneration++;
NSUInteger capturedGeneration = _errorGeneration;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
if (_errorGeneration == capturedGeneration)
_errorMessage.stringValue = @"";
});
}
基本上,您不会取消已分派的任务(因为您不能),但是如果它已过时,您可以让它什么也不做。