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