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 = [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 = 0
GCD_Demo5[2507:351136] Third Counter = 1
GCD_Demo5[2507:351136] Third Counter = 2
GCD_Demo5[2507:351136] Third Counter = 3
GCD_Demo5[2507:351134] First Counter = 0
GCD_Demo5[2507:351136] Third Counter = 4
GCD_Demo5[2507:351136] Third Counter = 5

performSelectorInBackground:withObject:方法为我们在后台创建了一个线程。这等同于我们为 selectors 创建一个新的线程。最重要的事情是我们必须记住通过此方法为 selector 创 建的线程,selector 必须有一个 autorelease pool,就想其它线程一样,在引用计数内存环境中。

时间: 2024-10-05 07:54:30

GCD12 :创建并发线程 和 调用后台线程的相关文章

使用boost线程定时器作为后台线程来切换主循环程序状态方法2

上一篇的方法主要使用的是:通过线程延时实 现的定时,并且只能定时一次,如果需要对此定时处理,就需要使用下面的定时器: #include "stdafx.h" #include <iostream> #include <boost/asio.hpp> #include <boost/thread.hpp> #include <boost/date_time/posix_time/posix_time.hpp> using namespace

JAVA并发,后台线程

1 package com.xt.thinks21_2; 2 3 import java.util.concurrent.TimeUnit; 4 5 /** 6 * 后台线程测试 7 * 8 * @author Administrator 9 * 10 */ 11 public class SimpleDaemonTest implements Runnable { 12 13 @Override 14 public void run() { 15 // TODO Auto-generated

【转载】Android中UI线程与后台线程交互设计的5种方法

原帖地址:http://www.cr173.com/html/19165_1.html 在android的设计思想中,为了确保用户顺滑的操作体验.一些耗时的任务不能够在UI线程中运行,像访问网络就属于这类任务.因此我们必须要重新开启一个后台线程运行这些任务.然而,往往这些任务最终又会直接或者间接的需要访问和控制UI控件.例如访问网络获取数据,然后需要将这些数据处理显示出来.就出现了上面所说的情况.原本这是在正常不过的现象了,但是android规定除了UI线程外,其他线程都不可以对那些UI控件访问

08_控制线程_后台线程(守护线程)

[后台线程] 后台线程(Daemon Thread):运行在后台,他的任务是为其它的线程提供服务,又称为"守护线程".JVM的垃圾回收线程就是典型的后台线程. [ 特征 ] 如果所有的前台线程都死亡,后台线程会自动死亡. 调用Thread对象的setDaemon(true)方法可以将指定的线程设置成后台线程. 当整个虚拟机中只剩下后台线程时,程序就没有继续运行的必要了,所以虚拟机也就退出了. Thread类提供了一个isDaemon()方法,用来判断指定线程是否为后台线程. [示例代码

Java多线程——&lt;五&gt;后台线程(daemon)

一.后台线程(守护线程) 学一个东西,最重要的一点就是,为什么要用它? 后台线程区别于普通线程,普通线程又可以称为用户线程,只完成用户自己想要完成的任务,不提供公共服务.而有时,我们希望编写一段程序,能够提供公共的服务,保证所有用户针对该线程的请求都能有响应. 仔细来看下后台线程的定义:指在程序运行的时候在后台提供一种通用服务的线程,并且这种线程并不属于程序中不可或缺的部分. 二.实现后台线程 1.我们先定义任务及响应的线程 定义任务:Thread.yield();让线程暂停一段时间 class

Android中UI线程与后台线程交互设计的5种方法

我想关于这个话题已经有很多前辈讨论过了.今天算是一次学习总结吧. 在android的设计思想中,为了确保用户顺滑的操作体验.一 些耗时的任务不能够在UI线程中运行,像访问网络就属于这类任务.因此我们必须要重新开启一个后台线程运行这些任务.然而,往往这些任务最终又会直接或者 间接的需要访问和控制UI控件.例如访问网络获取数据,然后需要将这些数据处理显示出来.就出现了上面所说的情况.原本这是在正常不过的现象了,但是 android规定除了UI线程外,其他线程都不可以对那些UI控件访问和操控.为了解决

后台线程(守护线程)

有一种线程,它是在后台运行的,它的任务是为其他的线程提供服务,这种线程被称为“后台线程”(Daemon Thread),又称为“守护线程”. 典型的后台线程是定时器”Timer"线程,他负责将固定的时间间隔发送给其他的线程. 后台线程经常用于任务结束时的善后处理.另外,后台线程的优先级要比其他的线程优先级低. 和后台线程相比,一般的线程称为“用户线程”.如果一个应用中只有后台线程在运行,JVM将退出该应用程序. 可以通过setDaemon(boolean d)来将一个普通的线程设置为后台线程.用

C#前台线程与后台线程的区别和联系 (转)

.Net的公用语言运行时(Common Language Runtime,CLR)能区分两种不同类型的线程:前台线程和后台线程.这两者的区别就是:应用程序必须运行完所有的前台线程才可以退出:而对于后台线程,应用程序则可以不考虑其是否已经运行完毕而直接退出,所有的后台线程在应用程序退出时都会自动结束. .net环境使用Thread建立的线程默认情况下是前台线程,即线程属性IsBackground=false,在进程中,只要有一个前台线程未退出,进程就不会终止.主线程就是一个前台线程.而后台线程不管

前台线程和后台线程的选择

什么时候用Thread ,, 什么时候用 ThreadPool.. 当符合以下条件时就用Thread对象,否则还是用线程池较好. 1.你需要线程允许一个非普通优先级.所有的线程池线程都允许在普通优先级.当然,这你可以改变,但是不推荐,在线程池操作过程中,优先级的改变不会持续. (线程的优先级..前台线程要高于后台线程.即使改变了后台线程的优先级..也不会持久) 2.你需要线程作为前台线程运转,从而防止程序终止一直到线程完成任务.线程池线程总是后台线程,如果CLR决定终止进程它们就不会完成任务.