bottom bar objective-c ios multithreading uikit core-foundation

objective-c - bottom - status bar ios



iOS inicio Subproceso (5)

Tengo un pequeño sqlitedb en mi dispositivo iOS. Cuando un usuario presiona un botón, obtengo los datos de sqlite y se lo muestro al usuario.

Esta parte de búsqueda quiero hacerlo en un hilo de fondo (para no bloquear el hilo principal de UI). Hago esto como tal -

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

Después de la búsqueda y un poco de procesamiento, necesito actualizar la interfaz de usuario. Pero dado que (como buena práctica) no deberíamos realizar la actualización de UI desde los hilos de fondo. Llamo a un selector en el hilo principal como tal -

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

Pero mi aplicación falla en el primer paso. es decir, comenzar un hilo de fondo. ¿No es esta una forma de iniciar subprocesos de fondo en iOS?

ACTUALIZACIÓN 1: Después de [self performSelectorInBackground.... obtengo esta stacktrace, no hay información alguna vez -

ACTUALIZACIÓN 2: incluso intenté, comenzando un hilo de fondo como así - [NSThread detachNewThreadSelector:@selector(getResultSetFromDB:) toTarget:self withObject:docids]; pero todavía obtengo la misma stacktrace.

Solo para que lo aclare, cuando realizo esta operación en el hilo principal todo funciona sin problemas ...

ACTUALIZAR 3 Este es el método que estoy tratando de ejecutar desde el fondo

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


Bueno, eso es bastante fácil en realidad con GCD. Un flujo de trabajo típico sería algo como esto:

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; }); });

Para obtener más información sobre GCD, puede consultar la documentación de Apple aquí.


Habilite NSZombieEnabled para saber qué objeto se está NSZombieEnabled y luego acceder a él. Luego, compruebe si getResultSetFromDB: tiene algo que ver con eso. También verifique si docids tiene algo adentro y si se conserva.

De esta manera puede estar seguro de que no hay nada mal.


La biblioteca sqlite predeterminada que viene con iOS no se compila utilizando la macro SQLITE_THREADSAFE en. Esta podría ser una razón por la cual tu código falla.


Si usa performSelectorInBackground:withObject: para generar un nuevo hilo, el selector realizado es responsable de configurar el grupo de autorrelease del nuevo thread, ejecutar el bucle y otros detalles de configuración - ver "Usando NSObject para engendrar un hilo" en la Guía de programación Threading de Apple.

Sin embargo, probablemente sería mejor usar Grand Central Dispatch :

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

GCD es una tecnología más nueva y es más eficiente en términos de sobrecarga de memoria y líneas de código.

Actualizado a Chris Nolet , quien sugirió un cambio que simplifica el código anterior y se mantiene al día con los últimos ejemplos de código GCD de Apple.


Swift 2.x respuesta:

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