NSOperationQueue menghindari mendorong pengontrol tampilan ke tumpukan pengontrol navigasi?

Saya memiliki pengontrol tampilan yang merupakan sub kelas UIViewController yang memiliki tampilan tabel ke dalamnya dan setiap baris dalam tampilan tabel ditautkan ke url xml yang berbeda. Saya membuat kelas parser yang merupakan sub kelas NSOperation dan menerapkan metode untuk mengurai file XML pada pilihan setiap baris sebagai,

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
    [self performSelectorOnMainThread:@selector(pushView) withObject:nil waitUntilDone:NO];
    [self performSelectorInBackground:@selector(parseOperation:) withObject:indexPath];
}

- (void)pushView {
    detailView = [[viewDetailsController alloc] initWithNibName:@"viewDetailsController" bundle:nil];
    [self.navigationController pushViewController:detailView animated:YES]; 
}

 - (void)parseOperation:(NSIndexPath *)indexPath {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    self.queue = [[NSOperationQueue alloc] init];
    parserClass *parser = [[parserClass alloc] initWithParseUrl:[[self.arrayOfUrls objectAtIndex:indexPath.row]delegate:self];
    [queue addOperation:parser];
    [parser release];
    [pool release];
}

Parser berfungsi dengan baik tetapi dalam metode delegasi khusus yang saya panggil untuk mendorong pengontrol tampilan di bagian atas tumpukan pengontrol navigasi, pengontrol tampilan diinisialisasi dengan benar tetapi pengontrol tampilan baru tidak didorong ke layar.

Saya telah mengedit pertanyaan untuk menggunakan utas utama dan utas latar belakang sementara utas latar berfungsi dengan benar untuk menguraikan utas utama hanya menginisialisasi dan tidak mendorong pengontrol tampilan. Apa masalahnya ?


person Sandeep    schedule 23.05.2011    source sumber


Jawaban (1)


Anda perlu mendorong pengontrol tampilan di thread utama. Gunakan performSelectorOnMainThread:withObject:waitUntilDone: untuk memanggil metode di thread utama.

Jika ada kemungkinan Anda akan memasukkan beberapa pengontrol tampilan, aplikasi Anda akan mogok jika pengontrol tampilan dimasukkan ke tumpukan saat pengontrol tampilan lainnya sedang dianimasikan. Dalam kasus ini, Anda harus menentukan animated:NO, atau mengumpulkan pengontrol tampilan dalam sebuah NSArray dan gunakan setViewControllers:animated: untuk menambahkannya ke tumpukan.


Menanggapi pertanyaan Anda yang diperbarui: Anda tidak perlu memanggil parseOperation: melalui performSelectorInBackground:withObject: karena NSOperationQueue akan tetap menjalankan NSOperation yang dibuatnya di thread terpisah. Saya sarankan menambahkan properti delegate ke subkelas NSOperation Anda dan mengikuti pola ini:

MyViewController.m:

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    MyParseOperation *parseOp = ...
    parseOp.delegate = self;
    [myOperationQueue addOperation:parseOp];
}

// Called by MyParseOperation
- (void)operationCompletedWithXML:(XML *)parsedXML
{
    // Use parsedXML to create and configure a view controller
    MyCustomViewController *vc = ...

    // Animation is OK since only one view controller will be created
    [self.navigationController pushViewController:vc animated:YES];
}

MyParseOperation.m:

// Call this method once the XML has been parsed
- (void)finishUp
{
    // Invoke delegate method on the main thread
    [self.delegate performSelectorOnMainThread:@selector(operationCompletedWithXML:) withObject:self.parsedXML waitUntilDone:YES];

    // Perform additional cleanup as necessary
}
person titaniumdecoy    schedule 23.05.2011
comment
Dalam hal ini Anda harus memiliki pengontrol tampilan yang baru saja Anda masukkan ke tumpukan untuk melakukan permintaan asinkron dan penguraian XML. - person titaniumdecoy; 28.05.2011