首页 > 代码库 > 多线程代码

多线程代码

 

    // NSObject

    // 在子线程中执行代码

    // 参数1: 执行的方法 (最多有一个参数,没有返回值)

    // 参数2: 传递给方法的参数

//    [self performSelectorInBackground:@selector(cycling:) withObject:@"obj1"];

    

    // 回到主线程更新页面

//    [self performSelectorOnMainThread:@selector(updateUI:) withObject:nil waitUntilDone:YES];

    

    

    // NSThread

    // 进入子线程

//    NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(cycling:) object:@"thread"];

//    [thread start]; // 启动线程执行

//    [thread release];

//

//    // 直接启动

//    [NSThread detachNewThreadSelector:@selector(cycling:) toTarget:self withObject:@"thread2"];

    

    

    // NSOperation

    /*

    // 通常使用NSOperation下的两个子类:NSInvocationOperation、NSBlockOperation

    // NSInvocationOperation

    NSInvocationOperation *invocationOperation = [[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(cycling:) object:@"invocationOperation"] autorelease];

//    [invocationOperation start]; // 启动任务

    

    // NSBlockOperation

    NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{

        for (int i = 0; i < 10000; i++) {

            NSLog(@"blockOperation: %i", i);

        }

    }];

//    [blockOperation start]; // 启动任务

    

    

    // 创建一个任务队列,NSOperationQueue

    NSOperationQueue *operationQueue = [[NSOperationQueue new] autorelease];

    // 当blockOperation中的任务执行完毕后,invocationOperation才开始执行

//    [invocationOperation addDependency:blockOperation];

    

    // 设置同时执行任务最大数

    operationQueue.maxConcurrentOperationCount = 1;

    

    // 添加任务到队列中

    [operationQueue addOperation:blockOperation];

    [operationQueue addOperation:invocationOperation];

    */

    

    /**

     *  GCD 分发队列 遵守FIFO原则

     *  串行队列:当一个任务执行完之后,才可以进行下一个任务的执行

     *  并行队列:任务在派发的时候是有顺序的,不用等到上一个任务执行完成之后再执行,同时执行

     */

    

    /**

     *  脱离线程:当线程内部的代码执行完毕之后,线程自动关闭。例如:NSThread / NSObject

     *  非脱离线程:当线程内部的代码执行完毕之后,线程不关闭,等待着下一次的使用。例如:NSOperationQueue

     */

    

    // 1. GCD 使用主队列实现任务的串行,主队列分派的任务,永远在主线程中

    dispatch_queue_t mainQueue = dispatch_get_main_queue();

//    dispatch_async(mainQueue, ^{

//        for (int i = 0; i < 1000; i++) {

//            NSLog(@"第一个任务:%d %@", i, [NSThread currentThread]);

//        }

//    });

//    dispatch_async(mainQueue, ^{

//        for (int i = 0; i < 1000; i++) {

//            NSLog(@"第二个任务:%d %@", i, [NSThread currentThread]);

//        }

//    });

//    dispatch_async(mainQueue, ^{

//        for (int i = 0; i < 1000; i++) {

//            NSLog(@"第三个任务:%d %@", i, [NSThread currentThread]);

//        }

//    });

    

    

    // 2. 使用自己创建出来的队列,实现任务的串行,新队列执行的任务,在子线程中执行

    // 参数1: 队列的标示

    // 参数2: 类型

    dispatch_queue_t myQueue = dispatch_queue_create("com.lanou3g.lesson_22.myQueue", DISPATCH_QUEUE_SERIAL);

//    dispatch_async(myQueue, ^{

//        for (int i = 0; i < 1000; i++) {

//            NSLog(@"第一个任务:%d %@", i, [NSThread currentThread]);

//        }

//    });

//    dispatch_async(myQueue, ^{

//        for (int i = 0; i < 1000; i++) {

//            NSLog(@"第二个任务:%d %@", i, [NSThread currentThread]);

//        }

//    });

//    dispatch_async(myQueue, ^{

//        for (int i = 0; i < 1000; i++) {

//            NSLog(@"第三个任务:%d %@", i, [NSThread currentThread]);

//        }

//    });

 

    

    // 3. 使用自己创建的队列,实现任务的并行,执行的任务在不同的子线程中执行

    dispatch_queue_t myQueue2 = dispatch_queue_create("com.lanou3g.lesson_22.myQueue2", DISPATCH_QUEUE_CONCURRENT);

//    dispatch_async(myQueue2, ^{

//        for (int i = 0; i < 1000; i++) {

//            NSLog(@"第一个任务:%d %@", i, [NSThread currentThread]);

//        }

//    });

//    dispatch_async(myQueue2, ^{

//        for (int i = 0; i < 1000; i++) {

//            NSLog(@"第二个任务:%d %@", i, [NSThread currentThread]);

//        }

//    });

//    dispatch_async(myQueue2, ^{

//        for (int i = 0; i < 1000; i++) {

//            NSLog(@"第三个任务:%d %@", i, [NSThread currentThread]);

//        }

//    });

 

    

    // 4. 使用系统的globle队列,实现任务的并行,在子线程中

    dispatch_queue_t globleQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

//    dispatch_async(globleQueue, ^{

//        for (int i = 0; i < 1000; i++) {

//            NSLog(@"第一个任务:%d %@", i, [NSThread currentThread]);

//        }

//    });

//    dispatch_async(globleQueue, ^{

//        for (int i = 0; i < 1000; i++) {

//            NSLog(@"第二个任务:%d %@", i, [NSThread currentThread]);

//        }

//    });

//    dispatch_async(globleQueue, ^{

//        for (int i = 0; i < 1000; i++) {

//            NSLog(@"第三个任务:%d %@", i, [NSThread currentThread]);

//        }

//    });

 

    // 让代码只执行一次

    for (int i = 0; i < 1000000; i++) {

        static dispatch_once_t onceToken;

        dispatch_once(&onceToken, ^{

            NSLog(@"只执行一次");

        });

    }

    

    // 让一段代码执行多次

    dispatch_apply(10, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(size_t t) {

        NSLog(@"多次执行");

    });

    

    // 让代码延迟几秒执行

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

        NSLog(@"延迟5秒执行");

    });

    /**

     *  1. 发送网络请求,获取网络数据的时候需要使用多线程(但是:我们创建网络请求的时候并不需要单独去开启子线程,系统会在方法内部帮我们做这件事)

     *  2. 当有耗时很长的计算的时候,建议使用多线程

     *  3. 当处理数据库中,或者其它位置大量数据的时候使用多线程

     *  4. 总结:将耗时比较长的代码,都放到子线程中运行

     *  5. 重点:页面的刷新必须回到主线程中

     */

}

 

 

#pragma mark 循环

- (void)cycling:(id)obj

{

    for (int i = 0; i < 10000; i++) {

        NSLog(@"%@: %d", obj, i);

    }

}

 

#pragma mark 发送网络图片请求

- (void)sendRequestForImageWithUrlStr:(NSString *)urlStr

{

    

    // http://pic.sucaiw.com/up_files/bizhi/a09ba7547e/sucaiw-cdscbj4023.jpg

    // 1. 直接通过NSData获取网络资源数据

    NSData *data = http://www.mamicode.com/[NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://pic.sucaiw.com/up_files/bizhi/a09ba7547e/sucaiw-cdscbj4023.jpg"]];

    

    // 2. 更新图片

    // 参数1: 主线程执行的方法

    // 参数2: 传递给方法的参数

    // 参数3: 是否等待子线程内执行完毕

    [self performSelectorOnMainThread:@selector(updateUI:)

                           withObject:[UIImage imageWithData:data]

                        waitUntilDone:YES];

}

 

#pragma mark - 更新页面

- (void)updateUI:(UIImage *)image

{

    _imageView.image = image;

}

 

 

- (IBAction)buttonAction:(UIButton *)sender

{

//    [self sendRequestForImageWithUrlStr:nil];

    

    // 子线程中请求图片

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

    

    

    

    

    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{

        

        

        for (int i = 0; i < 10; i++) {

            NSLog(@"%d", i);

        }

        

    });

    

    

    

    

多线程代码