如何使用延迟调用多个参数的方法

时间:2012-03-09 13:26:10

标签: ios methods selector

我试图在一段时间后调用一个方法。

我知道有一个解决方案:

[self performSelector:@selector(myMethod) withObject:nil afterDelay:delay];

我看到了this questionDocumentation

但我的问题是:我怎样才能调用一个带两个参数的方法?

例如:

- (void) MoveSomethigFrom:(id)from To:(id)to;

如何使用performSelector:withObject:afterDelay:

延迟调用此方法

由于

6 个答案:

答案 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

文件:
https://developer.apple.com/library/ios/#documentation/Cocoa/Reference/Foundation/Classes/NSInvocation_Class/Reference/Reference.html

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参数设计要调用的方法。把对象放在你需要的地方。

如果您希望通过其他方式访问该方法,请调用一个“解包”字典并使用显式参数调用预期方法的方法。