Frade
Frade

Reputation: 2988

how to call a method of multiple arguments with delay

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 question and 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:

Thanks

Upvotes: 39

Views: 36721

Answers (6)

Esqarrouth
Esqarrouth

Reputation: 39201

Here is how you can trigger a block after a delay in 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

Upvotes: 1

Martin Ullrich
Martin Ullrich

Reputation: 100701

use 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?

Upvotes: 114

Alexander Volkov
Alexander Volkov

Reputation: 8397

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
    });

Upvotes: 2

tooluser
tooluser

Reputation: 1542

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.

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.

Upvotes: 0

calimarkus
calimarkus

Reputation: 9977

Other ideas:

1) You could use NSInvocations:

+ (NSInvocation *)invocationWithMethodSignature:(NSMethodSignature *)signature
(>> see Eldar Markov's answer)

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

2) You could use a helper method..

[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..

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]];
}

Upvotes: 6

Eldar Markov
Eldar Markov

Reputation: 950

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:

@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

Upvotes: 7

Related Questions