首页 > 代码库 > GCD12 :创建并发线程 和 调用后台线程

GCD12 :创建并发线程 和 调用后台线程

问题:

你想在程序中运行单独的任务时,拥有最大的控制权。例如,你想要根据用户要求,来运行一个长计算请求,同时,主线程 UI 可以自由的与用户交互和做别的事情。
 
讨论:
在程序中使用线程:
- (void)viewDidLoad {    [super viewDidLoad];    // Do any additional setup after loading the view, typically from a nib.    NSString *fileToDownload = @"http://www.OReilly.com";    [NSThread detachNewThreadSelector:@selector(downloadNewFile:) toTarget:self withObject:fileToDownload];}- (void)downloadNewFile:(id)paramObject{    @autoreleasepool {        NSString *fileURl = (NSString *)paramObject;        NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:fileURl]];        NSURLResponse *response = nil;        NSError *error = nil;        NSData *downloadData = http://www.mamicode.com/[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];        if ([downloadData length] > 0) {            NSLog(@"下载成功");        }else{            NSLog(@"下载失败");        }    }}
在应用程序中,无论你使用多线程或不使用,至少有 1 个 线程被创建。该线程叫做”main UI 线程”,被附加到主事件处理循环中(main run loop)。 

 

每一个线程都需要创建一个 autorelease pool,当做是该线程第一个被创建的对象。如果不这样做,当线程退出的时候,你分配在线程中的对象会发生内存泄露。 

 

二  调用后台线程 

问题:

你想知道一个最简单的方法,来创建一个线程,而不需要直接处理线程。 
 
方案:
使用 NSObject 的实例方法 performSelectorInBackground:withObject: 

例子:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    // Override point for customization after application launch.    [self performSelectorInBackground:@selector(firstCounter) withObject:nil];    [self performSelectorInBackground:@selector(secondCounter) withObject:nil];    [self performSelectorInBackground:@selector(thirdCounter) withObject:nil];    return YES;}- (void)firstCounter{    @autoreleasepool{        NSUInteger counter = 0;        for (counter = 0;counter < 1000;counter++){            NSLog(@"First Counter = %lu", (unsigned long)counter);        }    }}- (void) secondCounter{    @autoreleasepool {        NSUInteger counter = 0;        for (counter = 0;counter < 1000;counter++){            NSLog(@"Second Counter = %lu", (unsigned long)counter); }    }}- (void) thirdCounter{    @autoreleasepool {        NSUInteger counter = 0;        for (counter = 0;counter < 1000;counter++){            NSLog(@"Third Counter = %lu", (unsigned long)counter); }    }}

输出为

GCD_Demo5[2507:351136] Third Counter = 0GCD_Demo5[2507:351136] Third Counter = 1GCD_Demo5[2507:351136] Third Counter = 2GCD_Demo5[2507:351136] Third Counter = 3GCD_Demo5[2507:351134] First Counter = 0GCD_Demo5[2507:351136] Third Counter = 4GCD_Demo5[2507:351136] Third Counter = 5
performSelectorInBackground:withObject:方法为我们在后台创建了一个线程。这等同于我们为 selectors 创建一个新的线程。最重要的事情是我们必须记住通过此方法为 selector 创 建的线程,selector 必须有一个 autorelease pool,就想其它线程一样,在引用计数内存环境中。 

 

 

 

 

GCD12 :创建并发线程 和 调用后台线程