Home » Swift » Swift alternative to performSelectorOnMainThread

Swift alternative to performSelectorOnMainThread

Posted by: admin November 30, 2017 Leave a comment

Questions:

I want to reload my table data inside a block in this method:

import UIKit
import AssetsLibrary

class AlbumsTableViewController: UITableViewController {

    var albums:ALAssetsGroup[] = []

    func loadAlbums(){
        let library = IAAssetsLibraryDefaultInstance

        library.enumerateGroupsWithTypes(ALAssetsGroupType(ALAssetsGroupAll),
            usingBlock: {(group, stop) in
                if group {
                    self.albums.append(group)
                }
                else {
                    dispatch_async(dispatch_get_main_queue(), {

                        self.tableView.reloadData()

                    })
                }
            }, failureBlock: { (error:NSError!) in println("Problem loading albums: \(error)") })

    }

    override func viewDidLoad() {
        super.viewDidLoad()
        loadAlbums()

        // Uncomment the following line to preserve selection between presentations
        // self.clearsSelectionOnViewWillAppear = false

        // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
        //self.navigationItem.rightBarButtonItem = self.editButtonItem
    }

But the else block will not execute. The error I get is:

'performSelectorOnMainThread' is unavailable: 'performSelector' methods are unavailable

So what is the alternative to 'performSelectorOnMainThread' in swift?

UPDATE:

I am now getting an abort error. Here is what the console looks like: http://cl.ly/image/3D0h1x433P0R

Answers:

This simple C-function:

dispatch_async(dispatch_get_main_queue(), {

        // DO SOMETHING ON THE MAINTHREAD
        self.tableView.reloadData()
        })

What about launching your function with:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), {

        loadAlbums()

})

in viewDidLoad()?

Questions:
Answers:

Use GCD in lieu of performSelector variations.

dispatch_async(dispatch_get_main_queue()) {
        () -> Void in
        self.doSomething()
    }

Questions:
Answers:

You are calling performSelectorOnMainThread on UIViewController instead of UITableView’s object

May be your code:

self.performSelectorOnMainThread(Selector(reloadData), withObject: self.tblMainTable, waitUntilDone: true)

Instead of:

self.tblMainTable.performSelectorOnMainThread(Selector("reloadData"), withObject: nil, waitUntilDone: true)

you are getting that message because UIViewController does’t have any method named “performSelectorOnMainThread”

Questions:
Answers:

//Xcode 8.2 // swift 3.0

I am accessing an API which gives the data regarding weather i.e ‘temperature’, ‘humidity’, ‘pressure’ etc after submitting the name or zipcode of any city.
So, That data need to be shown(It must be on Main Thread) on UI (the tableView)

self.performSelector(onMainThread: #selector(Home.DataOnUI), with: nil, waitUntilDone: true)

//

func DataOnUI() {

     self.tblView.reloadData()
}

P.S. Home is the class of UIViewController

Questions:
Answers:

Swift 3

DispatchQueue.main.async(execute:
{
    //Code to execute on main thread
})

Questions:
Answers:

Swift 3 / Xcode 8.2

Here is a Swift 3 way of doing things. Simply insert the time (in seconds) that you would like the code to execute after.

let delayTime = DispatchTime.now() + Double(Int64(20.0 * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC)
    DispatchQueue.main.asyncAfter(deadline: delayTime) {
        //Your code to run after 20 seconds
    }

Alternatively you could simply place your time delay in one-line notation like so:

DispatchQueue.main.asyncAfter(deadline: .now() + 10.0) {
    // Your code to run after 10 seconds
}