ios 如何延迟调用具有多个参数的方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9634790/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
how to call a method of multiple arguments with delay
提问by Frade
I'm trying to call a method after some delay.
我试图在延迟一段时间后调用一个方法。
I know there is a solution for that:
我知道有一个解决方案:
[self performSelector:@selector(myMethod) withObject:nil afterDelay:delay];
I saw this questionand Documentation
But my question is: How can I call a method that takes two parameters??
但我的问题是:如何调用带有两个参数的方法?
for instance:
例如:
- (void) MoveSomethigFrom:(id)from To:(id)to;
How would I call this method with delay, using performSelector:withObject:afterDelay:
我将如何延迟调用此方法,使用 performSelector:withObject:afterDelay:
Thanks
谢谢
回答by Martin Ullrich
use dispatch_after:
使用 dispatch_after:
double delayInSeconds = 2.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
//code to be executed on the main queue after delay
[self MoveSomethingFrom:from To:to];
});
EDIT 2015: For Swift, i recommend using this small helper method: dispatch_after - GCD in swift?
编辑 2015:对于 Swift,我建议使用这个小助手方法:dispatch_after - GCD in swift?
回答by Eldar Markov
You can also implement method in NSObject's category using NSInvocation object (works in all versions of iOS). I guess it should be something like this:
您还可以使用 NSInvocation 对象在 NSObject 的类别中实现方法(适用于所有版本的 iOS)。我想它应该是这样的:
@interface NSObject(DelayedPerform)
- (void)performSelector:(SEL)aSelector withObject:(id)argument0 withObject:(id)argument1 afterDelay:(NSTimeInterval)delay {
NSMethodSignature *signature = [self methodSignatureForSelector:aSelector];
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
[invocation setTarget:self];
[invocation setSelector:aSelector];
[invocation setArgument:&argument0 atIndex:2];
[invocation setArgument:&argument1 atIndex:3];
[invocation performSelector:@selector(invoke) withObject:nil afterDelay:delay];
}
@end
回答by calimarkus
Other ideas:
其他想法:
1) You could use NSInvocations:
1) 您可以使用 NSInvocations:
+ (NSInvocation *)invocationWithMethodSignature:(NSMethodSignature *)signature
(>> see Eldar Markov's answer)
+ (NSInvocation *)invocationWithMethodSignature:(NSMethodSignature *)signature
(>> 参见Eldar Markov 的回答)
Documentation:
https://developer.apple.com/library/ios/#documentation/Cocoa/Reference/Foundation/Classes/NSInvocation_Class/Reference/Reference.html
文档:https:
//developer.apple.com/library/ios/#documentation/Cocoa/Reference/Foundation/Classes/NSInvocation_Class/Reference/Reference.html
2) You could use a helper method..
2)您可以使用辅助方法..
[self performSelector:@selector(helperMethod) withObject:nil afterDelay:delay];
- (void) helperMethod
{
// of course x1 and x2 have to be safed somewhere else
[object moveSomethigFrom: x1 to: x2];
}
3) You could use an array or a dictionary as parameter..
3)您可以使用数组或字典作为参数..
NSArray* array = [NSArray arrayWithObjects: x1, x2, nil];
[self performSelector:@selector(handleArray:) withObject:array afterDelay:delay];
- (void) handleArray: (NSArray*) array
{
[object moveSomethigFrom: [array objectAtIndex: 0] to: [array objectAtIndex: 1]];
}
回答by Alexander Volkov
Swift:
迅速:
let delayInSeconds = 3.0;
let delay = delayInSeconds * Double(NSEC_PER_SEC)
let popTime = dispatch_time(DISPATCH_TIME_NOW, Int64(delay));
dispatch_after(popTime, dispatch_get_main_queue(), {
// DO SOMETHING AFTER 3 sec
});
回答by Esqarrouth
Here is how you can trigger a block after a delay in Swift:
以下是在 Swift 中延迟后触发块的方法:
runThisAfterDelay(seconds: 5) { () -> () in
print("Prints this 5 seconds later in main queue")
//Or perform your selector here
}
/// EZSwiftExtensions
func runThisAfterDelay(seconds seconds: Double, after: () -> ()) {
let time = dispatch_time(DISPATCH_TIME_NOW, Int64(seconds * Double(NSEC_PER_SEC)))
dispatch_after(time, dispatch_get_main_queue(), after)
}
The argument count does not really matter.
参数计数并不重要。
Its included as a standard function in my repo: https://github.com/goktugyil/EZSwiftExtensions
它作为标准函数包含在我的 repo 中:https: //github.com/goktugyil/EZSwiftExtensions
回答by tooluser
These will all work, but are all much more complex than is needed.
这些都可以工作,但都比需要的复杂得多。
Design the method to be called with an NSDictionary argument. Put the objects in it you need.
设计要使用 NSDictionary 参数调用的方法。把你需要的东西放进去。
If you want the method to be accessible by other means as well, call instead a method that 'unwraps' the dictionary and calls the intended method with explicit parameters.
如果您还希望通过其他方式访问该方法,请改为调用一个“解包”字典并使用显式参数调用预期方法的方法。