我试图在一段时间后调用一个方法。
我知道有一个解决方案:
[self performSelector:@selector(myMethod) withObject:nil afterDelay:delay];
我看到了this question和Documentation
但我的问题是:我怎样才能调用一个带两个参数的方法?
例如:
- (void) MoveSomethigFrom:(id)from To:(id)to;
如何使用performSelector:withObject:afterDelay:
由于
答案 0 :(得分:112)
使用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];
});
2015年编辑:对于Swift,我建议使用这个小帮手方法:dispatch_after - GCD in swift?
答案 1 :(得分:7)
您还可以使用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
答案 2 :(得分:6)
其他想法:
1) 您可以使用NSInvocations:
+ (NSInvocation *)invocationWithMethodSignature:(NSMethodSignature *)signature
(>>参见Eldar Markov's answer)
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)您可以使用数组或字典作为参数..
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]];
}
答案 3 :(得分:2)
夫特:
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
});
答案 4 :(得分:1)
以下是在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)
}
参数计数并不重要。
它作为我的回购中的标准功能包含在内: https://github.com/goktugyil/EZSwiftExtensions
答案 5 :(得分:0)
这些都可行,但都比需要的要复杂得多。
使用NSDictionary参数设计要调用的方法。把对象放在你需要的地方。
如果您希望通过其他方式访问该方法,请调用一个“解包”字典并使用显式参数调用预期方法的方法。