Быстрая альтернатива PerformSelectorOnMainThread

Я хочу перезагрузить данные таблицы внутри блока следующим методом:

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
    }

Но блок else не будет выполняться. Ошибка, которую я получаю:

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

Итак, какова альтернатива 'performSelectorOnMainThread' в Swift?

ОБНОВИТЬ:

Теперь я получаю ошибку прерывания.


person Amit Erandole    schedule 09.06.2014    source источник
comment
GCD уже некоторое время предпочтительнее performSelectorOnMainThread в Objective-C, ознакомьтесь с документацией здесь:developer.apple.com/library/ios/documentation/Performance/   -  person Jack    schedule 09.06.2014


Ответы (6)


Эта простая C-функция:

dispatch_async(dispatch_get_main_queue(), {

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

Как насчет запуска вашей функции с помощью:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), {

        loadAlbums()

})

в представленииDidLoad()?

person Ben    schedule 09.06.2014
comment
Пожалуйста. Пожалуйста, отметьте ответ как правильный, чтобы другие люди сразу увидели ответ :) - person Ben; 09.06.2014
comment
Я говорил слишком рано — теперь я получаю сообщение об ошибке, которое даже не знаю, как отладить: cl.ly/ image/1d272E263V2N — посмотрите, пожалуйста - person Amit Erandole; 09.06.2014
comment
Что вы видите в журнале консоли, когда происходит исключение (исключение просто означает, что был вызван abort()) - person David Berry; 09.06.2014
comment
Я пробовал это в своем собственном проекте, а также искал методы PerformOnThrad, все они устарели. - person Ben; 09.06.2014
comment
Обновите свой вопрос кодом, который вы используете в настоящее время, потому что предоставленный ответ, безусловно, должен работать. - person David Berry; 09.06.2014
comment
ваша функция loadAlbums() даже находится в другом потоке, чем основной поток? Это не должно создавать эту ошибку, но просто интересно. - person Ben; 10.06.2014
comment
У вас проблемы с симулятором или живым устройством? Я вижу проблему только в симуляторе. - person David Berry; 10.06.2014
comment
У меня была проблема с ячейкой с изменяемым размером в табличном представлении, ее размер изменяется в зависимости от того, есть ли у нее миниатюра или нет, и она отлично работала на каждом устройстве, кроме iPhone 6 Plus, но с этим она работает идеально! Спасибо! - person diegomen; 12.09.2014

Свифт 3

DispatchQueue.main.async(execute:
{
    //Code to execute on main thread
})
person Tom Howard    schedule 28.06.2017

Используйте GCD вместо вариантов PerformSelector.

dispatch_async(dispatch_get_main_queue()) {
        () -> Void in
        self.doSomething()
    }
person Ah Ryun Moon    schedule 28.06.2014

Вы вызываете performSelectorOnMainThread для UIViewController вместо объекта UITableView.

Может быть ваш код:

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

Вместо:

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

вы получаете это сообщение, потому что UIViewController не имеет метода с именем «performSelectorOnMainThread»

person Anand Suthar    schedule 06.08.2015

// Xcode 8.2 // свифт 3.0

Я получаю доступ к API, который предоставляет данные о погоде, т.е. «температура», «влажность», «давление» и т. д., после отправки названия или почтового индекса любого города. Итак, эти данные должны отображаться (Они должны быть в основном потоке) в пользовательском интерфейсе (tableView)

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

//

func DataOnUI() {

     self.tblView.reloadData()
}

P.S. Home — это класс UIViewController.

person Pankaj Nigam    schedule 29.12.2016
comment
Пожалуйста, также опишите свое решение в нескольких словах. - person Werner Henze; 29.12.2016

Swift 3/Xcode 8.2

Вот способ работы Swift 3. Просто введите время (в секундах), после которого вы хотите, чтобы код выполнялся.

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
    }

В качестве альтернативы вы можете просто поместить свою временную задержку в однострочную нотацию следующим образом:

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