网络请求,多线程,第三方分享iOS学习笔记程序员

iOS多线程总结

2017-02-14  本文已影响192人  45b645c5912e

进程

线程

线程串行

多线程

多线程的优缺点

多线程在iOS开发中的应用

NSThread

创建和启动线程

NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];
[thread start];
// 线程一启动,就会在线程thread中执行self的run方法
+(NSThread *)mainThread; // 获得主线程
-(BOOL)isMainThread; // 是否为主线程
+(BOOL)isMainThread; // 是否为主线程
NSThread *current = [NSThread currentThread];
-(void)setName:(NSString *)n;
-(NSString *)name;
[NSThread detachNewThreadSelector:@selector(run) toTarget:self withObject:nil];
[self performSelectorInBackground:@selector(run) withObject:nil];

控制线程状态

-(void)start; 
// 进入就绪状态 -> 运行状态。当线程任务执行完毕,自动进入死亡状态
+(void)sleepUntilDate:(NSDate *)date;
+(void)sleepForTimeInterval:(NSTimeInterval)ti;
// 进入阻塞状态
+(void)exit;
// 进入死亡状态

多线程的安全隐患

@synchronized(锁对象) { // 需要锁定的代码  }
//注意:锁定1份代码只用1把锁,用多把锁是无效的

原子和非原子属性

线程间通信

-(void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;
-(void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait;

GCD

简介

任务和队列

执行任务

dispatch_sync(dispatch_queue_t queue, dispatch_block_t block);
//queue:队列
//block:任务
dispatch_async(dispatch_queue_t queue, dispatch_block_t block);
dispatch_barrier_async(dispatch_queue_t queue, dispatch_block_t block);
//在前面的任务执行结束后它才执行,而且它后面的任务等它执行完成之后才会执行

队列的类型

容易混淆的术语

并发队列

dispatch_queue_t
dispatch_queue_create(const char *label, // 队列名称 
dispatch_queue_attr_t attr); // 队列的类型
dispatch_queue_t queue = dispatch_queue_create("com.520it.queue", DISPATCH_QUEUE_CONCURRENT);
dispatch_queue_t dispatch_get_global_queue(
dispatch_queue_priority_t priority, // 队列的优先级
unsigned long flags); // 此参数暂时无用,用0即可
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 

串行队列

// 创建串行队列(队列类型传递NULL或者DISPATCH_QUEUE_SERIAL)
dispatch_queue_t queue = dispatch_queue_create("com.520it.queue", NULL); 

各种队列的执行效果

/**
 * 同步函数+主队列 线程堵死
 */
-(void)syncMain{
    
    NSLog(@"begin");
    //1创建串行队列
    dispatch_queue_t queue = dispatch_get_main_queue();
    
    dispatch_sync(queue, ^{
        NSLog(@"1---%@",[NSThread currentThread]);
    });
    dispatch_sync(queue, ^{
        NSLog(@"2---%@",[NSThread currentThread]);
    });
    dispatch_sync(queue, ^{
        NSLog(@"3---%@",[NSThread currentThread]);
    });
    NSLog(@"end");

}
/**
 * 异步函数+主队列 只在主线程中执行任务
 */
-(void)asyncMain{
    //1创建串行队列
    dispatch_queue_t queue = dispatch_get_main_queue();
    
    dispatch_async(queue, ^{
        NSLog(@"1---%@",[NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"2---%@",[NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"3---%@",[NSThread currentThread]);
    });

}
/**
 * 同步函数+串行队列 不会开启新线程
 */
-(void)syncSerial{

    dispatch_queue_t queue = dispatch_queue_create("com.520.queue", DISPATCH_QUEUE_SERIAL);

    dispatch_sync(queue, ^{
        NSLog(@"1---%@",[NSThread currentThread]);
    });
    dispatch_sync(queue, ^{
        NSLog(@"2---%@",[NSThread currentThread]);
    });
    dispatch_sync(queue, ^{
        NSLog(@"3---%@",[NSThread currentThread]);
    });

}
/**
 * 异步函数+串行队列 会开启新的线程,但是任务是串行,执行完一个任务在执行下一个任务
 */
-(void)asyncSerial{
    
    //1创建串行队列
    dispatch_queue_t queue = dispatch_queue_create("com.520.queue", DISPATCH_QUEUE_SERIAL);

    dispatch_async(queue, ^{
        NSLog(@"1---%@",[NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"2---%@",[NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"3---%@",[NSThread currentThread]);
    });
}
/**
 * 同步函数+并行队列 不会开启新线程
 */
-(void)syncConcurrent{
    //1获得全局的并发队列
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    dispatch_sync(queue, ^{
        NSLog(@"1---%@",[NSThread currentThread]);
    });
    dispatch_sync(queue, ^{
        NSLog(@"2---%@",[NSThread currentThread]);
    });
    dispatch_sync(queue, ^{
        NSLog(@"3---%@",[NSThread currentThread]);
    });
}
/**
 * 异步函数+并行队列 可以同时开启多条线程
 */
-(void)asyncConcurrent{

    //1创建一个并发队列
//    dispatch_queue_t queue = dispatch_queue_create("com.520.queue", DISPATCH_QUEUE_CONCURRENT);
    
    //1获得全局的并发队列
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    dispatch_async(queue, ^{
        NSLog(@"1---%@",[NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"2---%@",[NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"3---%@",[NSThread currentThread]);
    });
}

线程间通信示例

dispatch_async(
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    // 执行耗时的异步操作...
      dispatch_async(dispatch_get_main_queue(), ^{
        // 回到主线程,执行UI刷新操作
        });
});

延时执行

[self performSelector:@selector(run) withObject:nil afterDelay:2.0];
// 2秒后再调用self的run方法
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    // 2秒后异步执行这里的代码...
});
[NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(test) userInfo:nil repeats:NO];

一次性代码

static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
    // 只执行1次的代码(这里面默认是线程安全的)
});

定时器

// 创建Timer
self.timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue());
// 设置定时器的触发时间(1秒后)和时间间隔(每隔2秒)
dispatch_source_set_timer(self.timer, dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC), 2 * NSEC_PER_SEC, 0);
// 设置回调
dispatch_source_set_event_handler(self.timer, ^{
    NSLog(@"Timer %@", [NSThread currentThread]);
});
// 开始定时器
dispatch_resume(self.timer);
//取消定时器
dispatch_cancel(self.timer);
self.timer = nil;
//
//  UIButton+countDown.m
//  计时器按钮
//
//  Created by 庄子豪 on 16/6/24.
//  Copyright © 2016年 zzh. All rights reserved.
//

#import "UIButton+countDown.h"

@implementation UIButton (countDown)
- (void)startWithTime:(NSInteger)timeLine title:(NSString *)title countDownTitle:(NSString *)subTitle mainColor:(UIColor *)mColor countColor:(UIColor *)color {
   
    //倒计时时间
    __block NSInteger timeOut = timeLine;
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_source_t _timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
    //每秒执行一次
    dispatch_source_set_timer(_timer, dispatch_walltime(NULL, 0), 1.0 * NSEC_PER_SEC, 0);
    dispatch_source_set_event_handler(_timer, ^{
       
        //倒计时结束,关闭
        if (timeOut <= 0) {
            dispatch_source_cancel(_timer);
            dispatch_async(dispatch_get_main_queue(), ^{
                self.backgroundColor = mColor;
                [self setTitle:title forState:UIControlStateNormal];
                self.userInteractionEnabled = YES;
            });
        } else {
            int seconds = timeOut % 60;
            NSString *timeStr = [NSString stringWithFormat:@"%0.2d", seconds];
            dispatch_async(dispatch_get_main_queue(), ^{
                self.backgroundColor = color;
                [self setTitle:[NSString stringWithFormat:@"%@%@",timeStr,subTitle] forState:UIControlStateNormal];
                self.userInteractionEnabled = NO;
            });
            timeOut--;
        }
    });
    dispatch_resume(_timer);
}
@end

快速迭代

dispatch_apply(10, dispatch_get_global_queue(0, 0), ^(size_t index){
    // 执行10次代码,index顺序不确定
});

队列组

dispatch_group_t group =  dispatch_group_create();
dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    // 执行1个耗时的异步操作
});
dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    // 执行1个耗时的异步操作
});
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
    // 等前面的异步操作都执行完毕后,回到主线程...
});

单例模式

+(instancetype)allocWithZone:(struct _NSZone *)zone
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instance = [super allocWithZone:zone];
    });
    return _instance;
}
+(instancetype)sharedInstance
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instance = [[self alloc] init];
    });
    return _instance;
}
-(id)copyWithZone:(struct _NSZone *)zone
{
    return _instance;
}

NSOperation

简介

NSOperation的子类

NSInvocationOperation

-(id)initWithTarget:(id)target selector:(SEL)sel object:(id)arg;
-(void)start;
//一旦执行操作,就会调用target的sel方法

NSBlockOperation

+(id)blockOperationWithBlock:(void (^)(void))block;
-(void)addExecutionBlock:(void (^)(void))block;

NSOperationQueue

-(void)addOperation:(NSOperation *)op;
-(void)addOperationWithBlock:(void (^)(void))block;

最大并发数

-(NSInteger)maxConcurrentOperationCount;
-(void)setMaxConcurrentOperationCount:(NSInteger)cnt;

队列的取消、暂停、恢复

-(void)cancelAllOperations;
//提示:也可以调用NSOperation的- (void)cancel方法取消单个操作
-(void)setSuspended:(BOOL)b; // YES代表暂停队列,NO代表恢复队列
-(BOOL)isSuspended;

操作依赖

[operationB addDependency:operationA]; // 操作B依赖于操作A

操作的监听

-(void (^)(void))completionBlock;
-(void)setCompletionBlock:(void (^)(void))block;

自定义NSOperation

上一篇 下一篇

猜你喜欢

热点阅读