Swift performSelector:withObject:afterDelay: is unavailable

IosObjective CSwiftXcode6

Ios Problem Overview


I have an app in Objective C that I'm transitioning to Swift. In Objective C, I have this method:

[self.view performSelector:@selector(someSelector) withObject:self afterDelay:0.1f];

I'm working with Swift and I can't figure out how to do this. I've tried:

self.view.performSelector(Selector("someSelector"), withObject: self, afterDelay: 0.1)

Here's the error that I get: 'performSelector' is unavailable: 'performSelector' methods are unavailable

What call would I use to call a method afterDelay?

UPDATE

Here's what I ended up with:

extension NSObject {

	func callSelectorAsync(selector: Selector, object: AnyObject?, delay: NSTimeInterval) -> NSTimer {
	
		let timer = NSTimer.scheduledTimerWithTimeInterval(delay, target: self, selector: selector, userInfo: object, repeats: false)
		return timer
	}

	func callSelector(selector: Selector, object: AnyObject?, delay: NSTimeInterval) {
	
		let delay = delay * Double(NSEC_PER_SEC)
		let time = dispatch_time(DISPATCH_TIME_NOW, Int64(delay))
		dispatch_after(time, dispatch_get_main_queue(), {
			NSThread.detachNewThreadSelector(selector, toTarget:self, withObject: object)
		})
	}
}

Ios Solutions


Solution 1 - Ios

Swift 4

DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
    // your function here
}

Swift 3

DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(0.1)) {
    // your function here
}

Swift 2

let dispatchTime: dispatch_time_t = dispatch_time(DISPATCH_TIME_NOW, Int64(0.1 * Double(NSEC_PER_SEC))) 
dispatch_after(dispatchTime, dispatch_get_main_queue(), { 
    // your function here 
})

Solution 2 - Ios

You could do this:

var timer = NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: Selector("someSelector"), userInfo: nil, repeats: false)

func someSelector() {
    // Something after a delay
}

###SWIFT 3

let timer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(someSelector), userInfo: nil, repeats: false)

func someSelector() {
    // Something after a delay
}

Solution 3 - Ios

Swift is statically typed so the performSelector: methods are to fall by the wayside.

Instead, use GCD to dispatch a suitable block to the relevant queue — in this case it'll presumably be the main queue since it looks like you're doing UIKit work.

EDIT: the relevant performSelector: is also notably missing from the Swift version of the NSRunLoop documentation ("1 Objective-C symbol hidden") so you can't jump straight in with that. With that and its absence from the Swiftified NSObject I'd argue it's pretty clear what Apple is thinking here.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionCody WintonView Question on Stackoverflow
Solution 1 - IosbrandonscriptView Answer on Stackoverflow
Solution 2 - IosStevenOjoView Answer on Stackoverflow
Solution 3 - IosTommyView Answer on Stackoverflow