Ich habe ein kleines sqlitedb in meinem iOS-Gerät. Wenn ein Benutzer eine Taste drückt, rufe ich die Daten von SQLite ab und zeige sie dem Benutzer.
Diesen Abrufteil möchte ich in einem Hintergrund-Thread machen (um den UI-Haupt-Thread nicht zu blockieren). Ich mache das so -
[self performSelectorInBackground:@selector(getResultSetFromDB:) withObject:docids];
Nach dem Abrufen und ein wenig Verarbeitung muss ich die Benutzeroberfläche aktualisieren. Da wir jedoch (als bewährte Methode) keine Aktualisierung der Benutzeroberfläche über Hintergrundthreads durchführen sollten. Ich rufe einen selector
On-Mainthread so an -
[self performSelectorOnMainThread:@selector(showResults) withObject:nil waitUntilDone:NO];
Aber meine App stürzt im ersten Schritt ab. dh einen Hintergrund-Thread starten. Ist dies nicht eine Möglichkeit, Hintergrund-Threads in iOS zu starten?
UPDATE 1: Nachdem [self performSelectorInBackground....
ich diesen Stacktrace erhalten habe, gibt es überhaupt keine Informationen -
UPDATE 2: Ich habe sogar versucht, einen Hintergrund-Thread wie diesen zu starten -
[NSThread detachNewThreadSelector:@selector(getResultSetFromDB:) toTarget:self withObject:docids];
aber ich bekomme immer noch den gleichen Stacktrace.
Nur damit ich klarstelle, wenn ich diesen Vorgang am Hauptthread durchführe, läuft alles reibungslos ...
UPDATE 3 Dies ist die Methode, die ich aus dem Hintergrund ausführen möchte
- (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;
}
quelle
docids
bleibt.docids
sindretain
. Ich habe es.h
@property (nonatomic, retain) NSMutableArray *docids;
get
; das sollte nur seinresultSetFromDB:
Antworten:
Wenn Sie
performSelectorInBackground:withObject:
einen neuen Thread erzeugen, ist der durchgeführte Selektor für das Einrichten des Autorelease-Pools, der Ausführungsschleife und anderer Konfigurationsdetails des neuen Threads verantwortlich - siehe "Verwenden von NSObject zum Spawnen eines Threads" im Apple Threading-Programmierhandbuch .Mit Grand Central Dispatch sind Sie wahrscheinlich besser dran :
GCD ist eine neuere Technologie und in Bezug auf Speicheraufwand und Codezeilen effizienter.
Aktualisiert mit einer Hutspitze an Chris Nolet , der eine Änderung vorschlug, die den obigen Code einfacher macht und mit den neuesten GCD-Codebeispielen von Apple Schritt hält.
quelle
[NSThread detachNewThreadSelector:@selector....
auch für?performSelectorInBackground:withObject:
"dasselbe, als ob Sie diedetachNewThreadSelector:toTarget:withObject:
MethodeNSThread
mit dem aktuellen Objekt, dem Selektor und dem Parameterobjekt als Parameter aufgerufen hätten ."(unsigned long)NULL
und0
in dieser Angelegenheit?Nun, das ist mit GCD eigentlich ziemlich einfach. Ein typischer Workflow wäre ungefähr so:
Weitere Informationen zu GCD finden Sie in der Dokumentation von Apple hier
quelle
Aktivieren NSZombieEnabled zu wissen , welches Objekt freigegeben wird und dann abgerufen. Dann prüfen Sie, ob das
getResultSetFromDB:
etwas damit zu tun hat. Überprüfen Sie auch, obdocids
sich etwas im Inneren befindet und ob es aufbewahrt wird.Auf diese Weise können Sie sicher sein, dass nichts falsch ist.
quelle
[self getResultSetFromDB:docids];
. Also when I try to call this method from background thread I do not reach
SpotMain * -Spiegel ... `, es stürzt kurz nach Eingabe des Hintergrundthreads ab ...Die mit iOS gelieferte Standard-SQLite-Bibliothek wird nicht mit dem Makro SQLITE_THREADSAFE kompiliert. Dies könnte ein Grund sein, warum Ihr Code abstürzt.
quelle
Schnelle 2.x Antwort:
quelle