多线程

作者: pingui | 来源:发表于2015-12-30 22:20 被阅读68次

    多线程

    先在storyboard上绘制两颗按钮,并且绑定事件。

    button.png

    先看下面一段代码:

    - (IBAction)blueButtonClicked:(UIButton *)sender {
        NSLog(@"蓝色按钮任务开始执行");
        // 模拟任务需要执行5s
        sleep(5);
        NSLog(@"蓝色按钮任务已经完成");
    }
    
    - (IBAction)yellowButtonClicked:(UIButton *)sender {
        NSLog(@"黄色按钮任务完成");
    }
    

    点击蓝色按钮之后就会卡在那里了,如果此时点击黄色按钮,不能看到NSLog打印的语句,但事实上任务已经执行了,必须等到蓝色按钮执行的事件执行完之后控制台才能打印出来。

    多线程

    
    - (void) bar:(UIButton *)sender{
        sender.enabled = YES;
        [sender setTitle:@"蓝色" forState:UIControlStateNormal];
    }
    
    - (IBAction)yellowButtonClicked:(UIButton *)sender {
        NSLog(@"黄色按钮任务完成");
    }
    
    • 第一种方式
    - (IBAction)blueButtonClicked:(UIButton *)sender {
        [sender setTitle:@"正在执行..." forState:UIControlStateNormal];
        sender.enabled = NO;
        
        // 提示:对于那些耗时间的任务基本上都应该放到其它的执行线程中
        // 不要阻塞主线程的执行 否则界面会出现卡顿或假死现象
        // 模拟任务需要执行5s
        //sleep(5);
        //NSLog(@"蓝色按钮任务已经完成");
        
        [self performSelectorInBackground:@selector(foo:) withObject:sender];
    }
    
    - (void) foo:(UIButton *)sender{
        sleep(5);
        NSLog(@"蓝色按钮任务已经完成");
        // 执行完之后要恢复按钮的状态
        //sender.enabled = YES;
        //[sender setTitle:@"蓝色" forState:0];
        // 提示:刷新视图界面要回到主线程执行,如果直接在这里执行 可能会失效
        [self performSelectorOnMainThread:@selector(bar:) withObject:sender waitUntilDone:YES];
    }
    
    • 第二种方式1
    - (IBAction)blueButtonClicked:(UIButton *)sender {
        [sender setTitle:@"正在执行..." forState:UIControlStateNormal];
        sender.enabled = NO;
        [NSThread detachNewThreadSelector:@selector(foo:) toTarget:self withObject:sender];
    }
    
    - (void) foo:(UIButton *)sender{
        sleep(5);
        NSLog(@"蓝色按钮任务已经完成");
        [self performSelectorOnMainThread:@selector(bar:) withObject:sender waitUntilDone:YES];
    }
    
    • 第二种方式2
    - (IBAction)blueButtonClicked:(UIButton *)sender {
        [sender setTitle:@"正在执行..." forState:UIControlStateNormal];
        sender.enabled = NO;
        
        NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(foo:) object:sender];
        
        [thread start];
        //[thread cancel];// 如果加上这句任务取消
        
        // 如果线程已经开始执行则无法取消
        
        // 下面的方法任务不能取消
        //[thread start];
        //sleep(1);
        //[thread cancel];
    }
    
    - (void) foo:(UIButton *)sender{
        // 休眠和退出都是只有正在执行的线程可以调用的方法
        // 因此在设计上这两个方法都是类方法而不是对象方法
        //[NSThread exit];
        
        sleep(5);
        NSLog(@"蓝色按钮任务已经完成");
        
        [self performSelectorOnMainThread:@selector(bar:) withObject:sender waitUntilDone:YES];
    }
    
    • 第三种方式
    - (IBAction)blueButtonClicked:(UIButton *)sender {
        [sender setTitle:@"正在执行..." forState:UIControlStateNormal];
        sender.enabled = NO;
        
        // 创建一个操作对象(将该操作放到一个队列中去执行)
        NSOperation *op = [NSBlockOperation blockOperationWithBlock:^{
            [self foo:sender];
        }];
        // 创建一个并发队列
        NSOperationQueue *queue = [[NSOperationQueue alloc] init];
        // 设置最大并发数
        queue.maxConcurrentOperationCount = 5;
        // 向队列中添加一个操作
        [queue addOperation:op]; 
    }
    
    - (void) foo:(UIButton *)sender{
        sleep(5);
        NSLog(@"蓝色按钮任务已经完成");
        
        // 创建一个操作对象
        NSOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(bar:) object:sender];
        // 向主线程操作队列中添加操作对象(操作放到主线程中执行)
        [[NSOperationQueue mainQueue] addOperation:op];
        
    }
    
    • 第四种方法
    - (IBAction)blueButtonClicked:(UIButton *)sender {
        [sender setTitle:@"正在执行..." forState:UIControlStateNormal];
        sender.enabled = NO;
    
        // GCD - Grand Center Dispatch
        
        dispatch_async(dispatch_get_global_queue(0, 0), ^{
            sleep(5);
            NSLog(@"蓝色按钮任务已经完成");
            dispatch_async(dispatch_get_main_queue(), ^{
                sender.enabled = YES;
                [sender setTitle:@"蓝色" forState:UIControlStateNormal];
            });
        });
    }
    

    相关文章

      网友评论

        本文标题:多线程

        本文链接:https://www.haomeiwen.com/subject/jzbihttx.html