Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

performSelector:withObject:afterDelay: is not passing an argument as expected

Tags:

swift

I am using performSelector to control the execution time of some methods in my controller. I would expect in this case the argument passed to animateIntroViews to be the value of with however it is not, instead it is some massively negative number like -7878379202283

func runOnRenderAnimations() -> Void {        
    perform(#selector(animateIntroViews), with: 0, afterDelay: 0.5)
    perform(#selector(animateIntroViews), with: 1, afterDelay: 2.5)
}

@objc fileprivate func animateIntroViews(textPosition: Int) -> Void {
    print(textPosition)
}
like image 561
Harry Blue Avatar asked Sep 07 '25 14:09

Harry Blue


2 Answers

perform doesn't work with parameters of primitive types like Int.

A better solution is to use DispatchQueue asyncAfter. This allows you to call the method normally.

func runOnRenderAnimations() -> Void {
    DispatchQueue.main.asyncAfter(deadline: now() + 0.5) {
        self.animateIntroViews(textPosition: 0)
    }
    DispatchQueue.main.asyncAfter(deadline: now() + 2.5) {
        self.animateIntroViews(textPosition: 1)
    }
}
like image 53
rmaddy Avatar answered Sep 10 '25 00:09

rmaddy


With your perform selector, you can pass argument as NSNumber instead of Int and get it as Number and Convert it to Int in your animateIntroViews function.

Example:

func runOnRenderAnimations() -> Void {

    perform(#selector(animateIntroViews), with: NSNumber(value: 0), afterDelay: 0.5)
    perform(#selector(animateIntroViews), with: NSNumber(value: 1), afterDelay: 2.5)
}

@objc fileprivate func animateIntroViews(textPosition: NSNumber) -> Void {

    print(textPosition.intValue)
}
like image 25
Natarajan Avatar answered Sep 10 '25 01:09

Natarajan