NSOperationQueue หลีกเลี่ยงการกดตัวควบคุมมุมมองลงในสแต็กตัวควบคุมการนำทางหรือไม่

ฉันมีตัวควบคุมมุมมองที่เป็นคลาสย่อยของ UIViewController ซึ่งมีมุมมองตารางอยู่และแต่ละแถวในมุมมองตารางเชื่อมโยงกับ URL xml ที่แตกต่างกัน ฉันสร้างคลาส parser ที่เป็นคลาสย่อยของ NSOperation และใช้วิธีการเพื่อแยกวิเคราะห์ไฟล์ XML ในการเลือกแต่ละแถวเป็น

- (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 ใช้งานได้ดี แต่ในวิธีการมอบหมายแบบกำหนดเอง ฉันได้เรียกให้กดตัวควบคุมมุมมองที่ด้านบนของสแต็กตัวควบคุมการนำทาง ตัวควบคุมมุมมองเริ่มต้นอย่างถูกต้อง แต่ตัวควบคุมมุมมองใหม่ไม่ได้ถูกผลักเข้าไปในหน้าจอ

ฉันได้แก้ไขคำถามสำหรับการใช้เธรดหลักและเธรดพื้นหลังในขณะที่เธรดพื้นหลังทำงานอย่างถูกต้องสำหรับการแยกวิเคราะห์เธรดหลักเพิ่งเริ่มต้นและไม่ผลักดันตัวควบคุมมุมมอง อะไรคือปัญหา ?


person Sandeep    schedule 23.05.2011    source แหล่งที่มา


คำตอบ (1)


คุณต้องกดตัวควบคุมมุมมองบนเธรดหลัก ใช้ performSelectorOnMainThread:withObject:waitUntilDone: เพื่อเรียกใช้เมธอดบนเธรดหลัก

หากมีความเป็นไปได้ที่คุณจะพุชตัวควบคุมมุมมองหลายตัว แอปของคุณจะหยุดทำงานหากตัวควบคุมมุมมองถูกผลักลงบนสแต็กในขณะที่อีกอันกำลังเคลื่อนไหวอยู่ ในกรณีนี้ คุณควรระบุ animated:NO หรือรวบรวมตัวควบคุมมุมมองใน NSArray และใช้ setViewControllers:animated: เพื่อเพิ่มลงในสแต็ก


เพื่อตอบคำถามที่อัปเดตของคุณ: คุณไม่จำเป็นต้องโทร parseOperation: ผ่าน performSelectorInBackground:withObject: เนื่องจาก NSOperationQueue จะดำเนินการ NSOperation ที่สร้างในเธรดแยกต่างหากต่อไป ฉันขอแนะนำให้เพิ่มคุณสมบัติ delegate ให้กับคลาสย่อย NSOperation ของคุณและทำตามรูปแบบนี้:

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
ในกรณีนั้น คุณควรมีตัวควบคุมมุมมองที่คุณเพิ่งกดลงบนสแต็กเพื่อดำเนินการคำขอแบบอะซิงโครนัสและการแยกวิเคราะห์ XML - person titaniumdecoy; 28.05.2011