прошивкой запустить фоновый поток



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



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



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



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



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



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



обновление 1: после [self performSelectorInBackground.... Я получаю этот stacktrace, нет информации, что так когда-либо -



enter image description here



обновление 2: я даже пробовал, начиная фоновый поток вот так -
[NSThread detachNewThreadSelector:@selector(getResultSetFromDB:) toTarget:self withObject:docids]; но все равно я получаю тот же stacktrace.



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



обновление 3 это метод, который я пытаюсь запустить из фона



- (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;
}
663   5  

5 ответов:

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

вам, вероятно, будет лучше использовать Grand Central Dispatch, но:

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

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


Обновлено С кончиком шляпы к Крис Nolet, который предложил изменение, которое делает приведенный выше код проще и идет в ногу с последними примерами кода GCD от Apple.

Ну, это довольно легко на самом деле с 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 здесь

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

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

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

Swift 2.х ответ:

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

Comments

    Ничего не найдено.