iphone ios ทำงานในเธรดแยกต่างหาก


96

วิธีที่ดีที่สุดในการรันโค้ดบนเธรดแยกคืออะไร ใช่ไหม:

[NSThread detachNewThreadSelector: @selector(doStuff) toTarget:self withObject:NULL];

หรือ:

    NSOperationQueue *queue = [NSOperationQueue new];
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self
                                                                        selector:@selector(doStuff:)
                                                                          object:nil;
[queue addOperation:operation];
[operation release];
[queue release];

ฉันทำวิธีที่สองแล้ว แต่ Wesley Cookbook ที่ฉันเคยอ่านใช้แบบแรก

คำตอบ:


244

ในความคิดของฉันวิธีที่ดีที่สุดคือการใช้ libdispatch หรือที่เรียกว่า Grand Central Dispatch (GCD) มัน จำกัด ให้คุณใช้ iOS 4 ขึ้นไป แต่มันก็ง่ายและใช้งานง่าย โค้ดในการประมวลผลบางอย่างบนเธรดพื้นหลังจากนั้นทำบางอย่างกับผลลัพธ์ในลูปรันหลักนั้นง่ายและกะทัดรัดอย่างเหลือเชื่อ:

dispatch_async( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    // Add code here to do background processing
    //
    //
    dispatch_async( dispatch_get_main_queue(), ^{
        // Add code here to update the UI/send notifications based on the
        // results of the background processing
    });
});

หากคุณยังไม่ได้ดำเนินการให้ดูวิดีโอจาก WWDC 2010 บน libdispatch / GCD / บล็อก


ฉันต้องการให้เข้ากันได้กับ 3.0 :(
Mike S

1
จากนั้นคิวการดำเนินการอาจเป็นทางออกที่ดีที่สุดในลำดับถัดไป นอกจากนี้ตรวจสอบให้แน่ใจว่าคุณไม่ดำดิ่งสู่การทำงานพร้อมกันเร็วเกินไป ลองเริ่มต้นด้วยการเขียนสิ่งที่เป็นเธรดเดียวและโปรไฟล์เพื่อดูว่าคุณจำเป็นต้องใช้มัลติเธรดหรือไม่หรือคุณสามารถออกแบบโค้ดเธรดเดียวของคุณให้มีประสิทธิภาพมากขึ้นได้ด้วยตัวเอง สำหรับงานง่ายๆบางครั้งคุณสามารถทำทุกสิ่งที่คุณต้องการด้วย performSelector: withObject: afterDelay: และหลีกเลี่ยงปัญหาทั้งหมดที่มาพร้อมกับการเขียนโปรแกรมแบบมัลติเธรด
Jacques

ขออภัยในการรื้อฟื้นสิ่งนี้ในภายหลัง แต่ถ้าฉันวางเมธอดการเรียกใช้ด้วย performSelector: withObject: afterDelay ฉันยังต้องใช้ NSAutoReleasePool ภายในเมธอด async หรือไม่ หากใช้พูลรีลีสอัตโนมัติหลักอย่างน่าอัศจรรย์ PerformSElector: afterDelay เป็นตัวเลือกที่เร็วกว่าอย่างแน่นอน
Mike S

ไม่ได้เนื่องจากเมธอดกำลังรันบนเธรดหลักซึ่งมีกลุ่มรีลีสอัตโนมัติของตัวเอง
Jacques

4
@ โจถ้าเสี่ยงที่จะพูดในสิ่งที่คุณรู้อยู่แล้วคุณไม่ควรติดนิสัยเขียนโค้ดที่ฆ่าเธรดมันจะไม่ช่วยคุณหรืออาชีพของคุณในระยะยาว ดูโพสต์นี้ (หรือหลายคนชอบ) ถึงเหตุผลที่ไม่ฆ่ากระทู้
MikeC

1

วิธีที่ดีที่สุดสำหรับการมัลติเธรดใน iOS คือการใช้ GCD (Grand Central Dispatch)

//creates a queue.

dispatch_queue_t myQueue = dispatch_queue_create("unique_queue_name", NULL);

dispatch_async(myQueue, ^{
    //stuffs to do in background thread
    dispatch_async(dispatch_get_main_queue(), ^{
    //stuffs to do in foreground thread, mostly UI updates
    });
});

0

ฉันจะลองใช้เทคนิคทั้งหมดที่คนโพสต์ไว้และดูว่าวิธีไหนเร็วที่สุด แต่ฉันคิดว่านี่เป็นวิธีที่ดีที่สุด

[self performSelectorInBackground:@selector(BackgroundMethod) withObject:nil];

สิ่งนี้เปิดใช้เธรดโดยมีลำดับความสำคัญต่ำ การใช้ gcd เป็นวิธีที่ดีที่สุดสำหรับการทำเธรด
Karsten

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.