Saya memiliki sqlitedb kecil di perangkat iOS saya. Ketika pengguna menekan tombol, saya mengambil data dari sqlite & menunjukkannya kepada pengguna.
Bagian pengambilan ini saya ingin melakukannya di thread latar belakang (untuk tidak memblokir thread utama UI). Saya melakukan ini seperti itu -
[self performSelectorInBackground:@selector(getResultSetFromDB:) withObject:docids];
Setelah mengambil & sedikit pemrosesan, saya perlu memperbarui UI. Tetapi karena (sebagai praktik yang baik) kita tidak boleh melakukan pembaruan UI dari utas latar belakang. Saya menyebutnya selector
di mainthread seperti itu -
[self performSelectorOnMainThread:@selector(showResults) withObject:nil waitUntilDone:NO];
Tetapi Aplikasi saya macet pada langkah pertama. yaitu memulai thread latar belakang. Bukankah ini cara untuk memulai utas latar belakang di iOS?
UPDATE 1: Setelah [self performSelectorInBackground....
saya mendapatkan stacktrace ini, tidak ada info apa pun -
PEMBARUAN 2: Saya bahkan mencoba, memulai utas latar belakang seperti itu -
[NSThread detachNewThreadSelector:@selector(getResultSetFromDB:) toTarget:self withObject:docids];
tetapi saya masih mendapatkan stacktrace yang sama.
Hanya untuk mengklarifikasi, ketika saya melakukan operasi ini di utas utama semuanya berjalan lancar ...
UPDATE 3 Ini adalah metode yang saya coba jalankan dari latar belakang
- (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;
}
sumber
docids
tersebut dipertahankan.docids
adalahretain
. Saya telah memasukkannya.h
sebagai@property (nonatomic, retain) NSMutableArray *docids;
get
; yang seharusnyaresultSetFromDB:
Jawaban:
Jika Anda menggunakan
performSelectorInBackground:withObject:
untuk menelurkan utas baru, maka pemilih yang dijalankan bertanggung jawab untuk menyiapkan kumpulan peluncuran otomatis utas baru, putaran proses, dan detail konfigurasi lainnya - lihat "Menggunakan NSObject untuk Menelurkan Utas" di Panduan Pemrograman Threading Apple .Anda mungkin lebih baik menggunakan Grand Central Dispatch , meskipun:
GCD adalah teknologi yang lebih baru, dan lebih efisien dalam hal overhead memori dan baris kode.
Diperbarui dengan tip topi untuk Chris Nolet , yang menyarankan perubahan yang membuat kode di atas lebih sederhana dan mengikuti contoh kode GCD terbaru Apple.
sumber
[NSThread detachNewThreadSelector:@selector....
juga berlaku untuk ?performSelectorInBackground:withObject:
"sama seperti jika Anda memanggildetachNewThreadSelector:toTarget:withObject:
metodeNSThread
dengan objek saat ini, pemilih, dan objek parameter sebagai parameter".(unsigned long)NULL
dan0
dalam hal ini?Sebenarnya cukup mudah dengan GCD. Alur kerja yang khas akan menjadi seperti ini:
Untuk informasi lebih lanjut tentang GCD, Anda dapat melihat dokumentasi Apple di sini
sumber
Aktifkan NSZombieEnabled untuk mengetahui objek mana yang dirilis dan kemudian diakses. Kemudian periksa apakah
getResultSetFromDB:
ada hubungannya dengan itu. Juga periksa apakahdocids
ada sesuatu di dalamnya dan apakah itu disimpan.Dengan cara ini Anda bisa yakin tidak ada yang salah.
sumber
[self getResultSetFromDB:docids];
. Also when I try to call this method from background thread I do not reach
cermin SpotMain * ... `, Ia crash segera setelah memasuki thread latar belakang ...Pustaka sqlite default yang disertakan dengan iOS tidak dikompilasi menggunakan makro SQLITE_THREADSAFE. Ini bisa menjadi alasan mengapa kode Anda mogok.
sumber
Jawaban Swift 2.x:
sumber