it-swarm.com.ru

iOS запускает фоновую тему

У меня есть небольшой sqlitedb в моем устройстве iOS. Когда пользователь нажимает кнопку, я извлекаю данные из sqlite и показываю их пользователю.

Эта часть извлечения я хочу сделать это в фоновом потоке (чтобы не блокировать основной поток пользовательского интерфейса). Я делаю это так -

[self performSelectorInBackground:@selector(getResultSetFromDB:) withObject:docids];

После извлечения и небольшой обработки мне нужно обновить интерфейс. Но поскольку (как хорошая практика) мы не должны выполнять обновление пользовательского интерфейса из фоновых потоков. Я называю selector на mainthread примерно так -

[self performSelectorOnMainThread:@selector(showResults) withObject:nil waitUntilDone:NO];

Но мое приложение вылетает на первом этапе. то есть запуск фонового потока. Разве это не способ запустить фоновые темы в iOS?

ОБНОВЛЕНИЕ 1: После [self performSelectorInBackground.... я получаю эту трассировку стека, никакой информации, что когда-либо -

enter image description here

ОБНОВЛЕНИЕ 2: Я даже пытался запустить фоновый поток, например, - [NSThread detachNewThreadSelector:@selector(getResultSetFromDB:) toTarget:self withObject:docids];, но все равно получаю ту же самую трассировку стека.

Просто чтобы уточнить, когда я выполняю эту операцию в основном потоке, все идет гладко ...

ОБНОВЛЕНИЕ Это метод, который я пытаюсь запустить из фона

- (void)getResultSetFromDB:(NSMutableArray *)toProceessDocids
{
    SpotMain *mirror = [[SpotMain alloc] init];
    NSMutableArray *filteredDocids = toProceessDocids;

    if(![gMediaBucket isEqualToString:@""])
        filteredDocids = [mirror FetchDocIdsForMediaBucketWithDocID:filteredDocids mBucket:gMediaBucket numRes:-1];
    if(![gMediaType isEqualToString:@""])
        filteredDocids = [mirror FetchDocIdsForMediaType:filteredDocids mediaType:gMediaType numRes:-1];
    if(![gPlatform isEqualToString:@""])
        filteredDocids = [mirror FetchDocIdsForPlatformID:filteredDocids platformId:@"1" numRes:-1];

    self.resultSet = [mirror FetchObjectFromDocid:filteredDocids];
    [filteredDocids release];
    [mirror release];

    [self performSelectorOnMainThread:@selector(showResults) withObject:nil waitUntilDone:NO];
    return;
}
116
Srikar Appalaraju

Если вы используете performSelectorInBackground:withObject: для создания нового потока, то выполненный селектор отвечает за настройку пула автоматического выпуска нового потока, цикла выполнения и других деталей конфигурации - см. "Использование NSObject для создания потока" в Apple Руководство по программированию потоков .

Возможно, вам лучше использовать Grand Central Dispatch , хотя:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    [self getResultSetFromDB:docids];
});

GCD - более новая технология, и она более эффективна с точки зрения затрат памяти и строк кода.


Обновлен с подсказкой для шляпы: Chris Nolet , который предложил изменение, которое упростит приведенный выше код и будет соответствовать последним версиям Apple. Примеры кода GCD.

269
Scott Forbes

Ну, на самом деле это довольно легко с GCD. Типичный рабочий процесс будет выглядеть примерно так:

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul);
    dispatch_async(queue, ^{
        // Perform async operation
        // Call your method/function here
        // Example:
        // NSString *result = [anObject calculateSomething];
                dispatch_sync(dispatch_get_main_queue(), ^{
                    // Update UI
                    // Example:
                    // self.myLabel.text = result;
                });
    });

Подробнее о GCD вы можете узнать в документация Apple здесь

8
Pawan Ahire

Включите NSZombieEnabled , чтобы узнать, какой объект был освобожден и затем доступен. Затем проверьте, имеет ли getResultSetFromDB: какое-либо отношение к этому. Также проверьте, есть ли внутри docids что-нибудь и сохраняется ли оно.

Таким образом, вы можете быть уверены, что в этом нет ничего плохого.

4
Nicolas S

Swift 2.x ответ:

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
        self.getResultSetFromDB(docids)
    }
2
Crashalot

Библиотека sqlite по умолчанию, которая поставляется с iOS, не скомпилирована с использованием макроса SQLITE_THREADSAFE. Это может быть причиной сбоя вашего кода.

2
Mugunth