Tengo un pequeño sqlitedb en mi dispositivo iOS. Cuando un usuario presiona un botón, obtengo los datos de sqlite y se los muestro al usuario.
Esta parte de búsqueda la quiero hacer en un hilo de fondo (para no bloquear el hilo principal de la interfaz de usuario). Hago esto así -
[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 la interfaz de usuario desde subprocesos en segundo plano. Llamo selector
a mainthread así -
[self performSelectorOnMainThread:@selector(showResults) withObject:nil waitUntilDone:NO];
Pero mi aplicación falla en el primer paso. es decir, iniciar un hilo de fondo. ¿No es esta una forma de iniciar subprocesos en segundo plano en iOS?
ACTUALIZACIÓN 1: Después de [self performSelectorInBackground....
obtener este stacktrace, no hay información en absoluto -
ACTUALIZACIÓN 2: Incluso lo intenté, comenzando un hilo de fondo como ese,
[NSThread detachNewThreadSelector:@selector(getResultSetFromDB:) toTarget:self withObject:docids];
pero aún obtengo el mismo seguimiento de pila.
Solo para aclarar, cuando realizo esta operación en el hilo principal, todo funciona sin problemas ...
ACTUALIZACIÓN 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;
}
fuente
docids
se conserve.docids
sonretain
. Lo he puesto.h
como@property (nonatomic, retain) NSMutableArray *docids;
get
; eso debería serresultSetFromDB:
Respuestas:
Si utiliza
performSelectorInBackground:withObject:
para generar un nuevo hilo, entonces el selector realizado es responsable de configurar el grupo de liberación automática del nuevo hilo, el ciclo de ejecución y otros detalles de configuración - consulte "Uso de NSObject para generar un hilo" en la Guía de programación de subprocesos de Apple .Sin embargo, probablemente sería mejor usar Grand Central Dispatch :
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.
Se actualizó con un toque de sombrero 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.
fuente
[NSThread detachNewThreadSelector:@selector....
también a?performSelectorInBackground:withObject:
"es lo mismo que si llamaras aldetachNewThreadSelector:toTarget:withObject:
método deNSThread
con el objeto actual, el selector y el objeto de parámetro como parámetros".(unsigned long)NULL
y0
en este asunto?Bueno, eso es bastante fácil en realidad con GCD. Un flujo de trabajo típico sería algo como esto:
Para obtener más información sobre GCD, puede consultar la documentación de Apple aquí.
fuente
Habilite NSZombieEnabled para saber qué objeto se libera y luego se accede. Luego verifique si
getResultSetFromDB:
tiene algo que ver con eso. También verifique sidocids
tiene algo adentro y si está retenido.De esta forma, puede estar seguro de que no hay ningún problema.
fuente
[self getResultSetFromDB:docids];
. Also when I try to call this method from background thread I do not reach
SpotMain * espejo ... `, Se bloquea poco después de ingresar al hilo de fondo ...La biblioteca sqlite predeterminada que viene con iOS no se compila con la macro SQLITE_THREADSAFE en. Esta podría ser una razón por la que su código falla.
fuente
Respuesta rápida 2.x:
fuente