iOS多線程-NSThread

本文轉載自嘟嘟夜未央的博文:http://www.cnblogs.com/huluo666/p/3645889.html,修改了部分代碼和貼圖,若有侵犯版權請與我聯繫刪除。html

    多線程這個概念的接觸是蠻早的時候了,當時仍是單核單CPU的時候,Thread這個概念已經出現了,當時比較流行的方案是時間片輪流,線程能夠優先級搶佔,但一次只能運行一個線程,實際上多線程是不能真正並行處理的,只是宏觀上表現的多線程在齊頭並進。如今硬件進步了不少,多核的CPU時代來臨了,因而線程開始了真正意義上的並行處理,多線程也做爲愈來愈重要的一個部分須要掌握。ios

    iOS中關於線程的建立和運行,提供了3種方法:NSThread,NSOperation和GCD。這三種方式抽象程度愈來愈高,因此編寫代碼是愈來愈簡單的。多線程

    咱們先來看NSThread吧。app

    NSThread比其餘兩個都要更輕量級,但須要本身來管理線程的生命週期和同步,代碼的編寫上比其餘兩個複雜。對於線程的技術,蘋果的官方文檔上給出了一張表:ide

 

Technologyflex

Descriptionui

Cocoa threadsthis

Cocoa implements threads using the NSThread class. Cocoa also provides methods onNSObject for spawning new threads and executing code on already-running threads. For more information, see 「Using NSThread」 and 「Using NSObject to Spawn a Thread.」url

POSIX threadsspa

POSIX threads provide a C-based interface for creating threads. If you are not writing a Cocoa application, this is the best choice for creating threads. The POSIX interface is relatively simple to use and offers ample flexibility for configuring your threads. For more information, see 「Using POSIX Threads」

Multiprocessing Services

Multiprocessing Services is a legacy C-based interface used by applications transitioning from older versions of Mac OS. This technology is available in OS X only and should be avoided for any new development. Instead, you should use the NSThread class or POSIX threads. If you need more information on this technology, see Multiprocessing Services Programming Guide.

 

    蘋果雖然支持3種技術,但咱們實際中最經常使用的也就是第一種,使用NSThread來進行線程的控制。NSThread有2種初始化方式,一種是傳統的init方式(initWithTarget:selector:object:),另外一種是類方法(+ detachNewThreadSelector:toTarget:withObject:)

    initWithTarget方法用法以下:

NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(downloadImage:) object:IMAGE_URL];
[thread start];

    這個裏面的@selector就是線程的入口點,只能接受一個傳入參數,而且沒有返回值。還有一個須要強調一下,init僅僅是建立了線程,要線程運行還須要調用start方法。

    若是要換成detachNewThreadSelector的類方法,用法以下:

[NSThread detachNewThreadSelector:@selector(downloadImage:) toTarget:self withObject:IMAGE_URL];

    咱們能夠看到參數很像,但線程會當即運行,不須要手動調用start方法。

    咱們仍是看代碼吧,這個代碼很簡單,是實現後臺下載,並在一張UIImage上顯示。

    用NSThread的方法,採用initWithTarget的作法:

#import "ViewController.h"

#define IMAGE_URL @"http://williamzhang-public.qiniudn.com/DSC_0069.jpg"

@interface ViewController ()

@end

@implementation ViewController
@synthesize imageView;

- (void)downloadImage:(NSString*)url
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    NSData *data = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:url]];
    UIImage *image = [[UIImage alloc] initWithData:data];
    
    if (image) {
        [self performSelectorOnMainThread:@selector(updateUI:) withObject:image waitUntilDone:YES];
    }
    [pool drain];
}

- (void)updateUI:(UIImage*)image
{
    self.imageView.image = image;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(downloadImage:) object:IMAGE_URL];
    [thread start];
    

}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void)dealloc {
    [imageView release];
    [super dealloc];
}
@end

    在viewDidLoad中,咱們生成一個線程並運行,線程的入口點就是downloadImage:方法,用來下載圖片,並通知主線程刷新界面。
    若是採用detachNewThreadSelector方法就是把viewDidLoad方法稍微改改就行:

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    [NSThread detachNewThreadSelector:@selector(downloadImage:) toTarget:self withObject:IMAGE_URL];
}

    咱們在開發中始終須要記住main thread是不能運行長時間沒有響應的任務的,上面的例子就是一個很典型的多線程應用,可是蘋果仍是提供了一種更近簡單的方式幫助咱們簡化開發的麻煩。這就是NSObject類提供的performSelectorInBackground:withObject:方法和performSelectorOnMainThread:withObject:waitUntilDone:方法。在上面的例子中已經使用了performSelectorOnMainThread:withObject:waitUntilDone:方法,在下載圖片後就是用這個方法讓主線程刷新UI的。

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    [self performSelectorInBackground:@selector(downloadImage:) withObject:IMAGE_URL];
}

    若是這樣寫的話,雖然也是本質仍是多線程,但你根本感受不到NSThread的存在,能夠簡單的理解就運行一個後臺的任務,在很多場合仍是更簡單清晰一些。

    最後要說的一個是生成的線程,對內存的管理也是要本身負責的,因此須要生成autorelease pool,若是你開啓了ARC功能,那麼能夠簡單的用@autoreleasepool這個關鍵字。

相關文章
相關標籤/搜索