//
// TableViewController.m
// UI-W6-L22-Thread
//
// Created by lanou3g on 15/10/19.
// Copyright (c) 2015年 Seth. All rights reserved.
//
#import "TableViewController.h"
@interface TableViewController ()
//线程队列
@property (nonatomic,strong)NSOperationQueue *operationQueue;
@end
@implementation TableViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;'
//返回主线程的方法
dispatch_sync(dispatch_get_main_queue(), ^{//从子线程回到主线程的方法,但是如果在主线程里面用这个方法,会回不去,卡住程序运行
// NSLog(@"阻塞了");
});
//把耗时的操作放在子线程里执行; 关于UI的添加和刷新都必须在主线程里操作
}
- (IBAction)leijai:(UIButton *)sender {
int sum = 0;
for (int i = 1; i <= 635500000; i++) {
sum = sum + i;
}
NSLog(@"sum===%d",sum);
}
-(void)printNumbers {
[[NSThread currentThread] cancel];
for (int i = 0; i < 100 ; i++) {
NSLog(@"%d,当前线程%@",i,[NSThread currentThread] );
}
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
#warning Potentially incomplete method implementation.
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
#warning Incomplete method implementation.
// Return the number of rows in the section.
return 20;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath];
// Configure the cell...
/**
*多线程 1,NSThread
*/
//NSThread 创建初始化initwithTarget:执行者selector:选择器 object:参数对象
//通过init方法创建NSThread对象,需要手动开启start
//2 NSThread开启线程并自动执行
// [NSThread detachNewThreadSelector:@selector(printNumbers) toTarget:self withObject:nil];
// [self printNumbers];
/**
*NSOPerationQueue 线程队列
*/
//1,NSInvocationOperation操作
// NSInvocationOperation *iOP = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(printNumbers) object:nil];
//Operation 是不能自己执行,需要通过队列进行调用
// [[NSOperationQueue mainQueue] addOperation:iOP];
//2,NSBlockOperation
NSBlockOperation *bOp = [[NSBlockOperation alloc] init];
//以代码块的方式添加操作
[bOp addExecutionBlock:^{
for (int i = 0; i < 100 ; i++) {
NSLog(@"%d,当前线程%@",i,[NSThread currentThread] );
}
}];
//添加到线程队列
// [[NSOperationQueue mainQueue] addOperation:bOp];
[self.operationQueue addOperation:bOp];//
NSLog(@"%@",self.operationQueue.name);
return cell;
}
//operationQueue的get方法
-(NSOperationQueue *)operationQueue {
if (!_operationQueue) {
_operationQueue = [[NSOperationQueue alloc] init];
[_operationQueue setName:@"哈哈"];
}
return _operationQueue;
}
@end
笔记文件2
//
// ViewController.m
// UI-L22-Review-Seth
//
// Created by lanou3g on 15/10/19.
// Copyright (c) 2015年 Seth. All rights reserved.
//
#import "ViewController.h"
@interface ViewController ()
//线程队列
@property (nonatomic,strong)NSOperationQueue *opertationQueue;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//一个进程是由一个或多个线程组成,进程只负责资源的调度和分配,线程才是程序真正的执行单元,负责代码的执行.
//每个正在运行的程序,至少包含一个线程,这个线程叫做主线程.
//主线程在程序启动时被创建,用于执行main函数
//只有一个主线程的程序,称作单线程程序
//主线程负责执行程序的所有代码,(ui展现及刷新,网络请求,)这些程序只能顺序执行,无法并发执行.
//ios允许用户自己开辟新的线程,相对于主线程来说,这些线程,称作子线程.
//子线程与主线程是独立的运行单元,互不影响,能够并发执行
//ios中关于UI的刷新和添加必须在主线程中操作!!
/**
*NSThread 是一个轻量级的多线程,
*/
//1, NSThread开启线程并自动执行
[NSThread detachNewThreadSelector:@selector(printNumbers:) toTarget:self withObject:@"1111"];
[NSThread detachNewThreadSelector:@selector(printNumbers:) toTarget:self withObject:@"2222"];
//2,NSThread 创建初始化initWithTarget:执行者 selector:选择器 object:参数对象
//通过init方法创建NSThread对象,需要手动开启start
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(printNumbers:) object:@"333"];
[thread start];
//两种方式区别:第一种方式会立即调用并执行线程,第二种必须调用start方法后才会开始执行线程,在此之前可以对线程进行一些设置,比如线程优先级等;
//使用类方法创建的线程不需要进行内存清理,使用initwithTarget方法创建的线程需要释放内存
// [self printNumbers]; //走主线程 main
/**
* NSOPerationQueue 线程队列
*/
//1, NSInvocationOperation 操作
NSInvocationOperation *iOP = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(printNumbers:) object:@"线程队列iOP1"];
//operation不能自己执行 ,需要通过队列进行调用
[[NSOperationQueue mainQueue] addOperation:iOP];
//2, NSBlockOperation
NSBlockOperation *bbbOp = [[NSBlockOperation alloc] init];
//以代码块方式添加操作
[bbbOp addExecutionBlock:^{
for (int i = 0; i < 11; i++) {
NSLog(@"%d,%@",i,[NSThread currentThread]);
}
}];
//添加到线程队列
// [[NSOperationQueue mainQueue] addOperation:bbbOp];
[self.opertationQueue addOperation:bbbOp];
}
-(void)printNumbers:(NSString *)string {
[[NSThread currentThread]cancel];
for (int i = 0; i < 15; i++) {
NSLog(@"%d,当前线程%@",i,[NSThread currentThread]);
NSLog(@"我是第%@子线程",string);
}
}
//operationQueue的get方法
-(NSOperationQueue *)opertationQueue {
if (!_opertationQueue) {
_opertationQueue = [[NSOperationQueue alloc] init];
[_opertationQueue setName:@"啊啊啊啊啊"];
}
return _opertationQueue;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
笔记文件3–共产党 GCD
//
// ViewController.m
// UI-W6-L22-GCD
//
// Created by lanou3g on 15/10/19.
// Copyright (c) 2015年 Seth. All rights reserved.
//
#import "ViewController.h"
@interface ViewController ()
- (IBAction)dicclickMaxConButton:(UIButton *)sender;
- (IBAction)didClickDependButton:(UIButton *)sender;
//线程队列
@property (nonatomic,strong)NSOperationQueue *operationQueue;
//10.20
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
- (IBAction)didNsobjectLoadImageButton:(id)sender;
//总票数
@property (nonatomic,assign)NSInteger count;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.count = 100;
// Do any additional setup after loading the view, typically from a nib.
//主队列 主线程
NSLog(@"主队列 :%@",[NSOperationQueue mainQueue]);
NSLog(@"主线程 :%@",[NSThread mainThread]);
//NSBlockOperation 创建方式 ,可以便利构造,直接添加block
NSBlockOperation *bOp = [NSBlockOperation blockOperationWithBlock:^{
for (int i = 0; i < 100; i++) {
NSLog(@"%d, 当前线程:%@",i,[NSThread currentThread]);
}
}];
NSBlockOperation *bOp1 = [NSBlockOperation blockOperationWithBlock:^{
for (int i = 0; i < 100; i++) {
NSLog(@"%d,bOp1当前线程: %@",i,[NSThread currentThread]);
}
}];
NSBlockOperation *bOp2 = [NSBlockOperation blockOperationWithBlock:^{
for (int i = 0; i < 100; i++) {
NSLog(@"%d,******当前线程: %@",i,[NSThread currentThread]);
}
}];
//添加到主队列
[[NSOperationQueue mainQueue] addOperation:bOp];
//自定义队列
self.operationQueue = [[NSOperationQueue alloc] init];
[self.operationQueue addOperation:bOp1];
[self.operationQueue addOperation:bOp2];
self.operationQueue = [[NSOperationQueue alloc] init];
//设置最大并发数
self.operationQueue.maxConcurrentOperationCount = 4;
//NSObject 简单后台方法 nsobject任何子类都可以调用
[self performSelectorInBackground:@selector(printNumber:) withObject:nil];
#pragma ----GCD 中央派发机制
/** Grand Central Dispath
* 基于函数,使用分发队列
*/
//1,主线程队列 , 等同[NSOperationQueue mainQueue] ,串行
//2,全局线程队列, 后台队列,并行
//3,自定义线程队列,DISPATCH_QUEUE_SERIAL 串行, DISPATCH_QUEUE_CONCURRENT 并行
//创建一个自定义队列
dispatch_queue_t myQueue = dispatch_queue_create("com.lanou3g.www.myQueue", DISPATCH_QUEUE_PRIORITY_DEFAULT);//字符串为c语言字符串,无@,书写格式倒置域名格式
//队列优先级,串行/并行
//dispatch_async(队列,执行block);
//dispatch_sync(队列,执行block);
dispatch_async(myQueue, ^{
[self printNumber:@"GCD"];
[self printNumber:@"G1"];
});
//添加操作
dispatch_async(myQueue, ^{
[self printNumber:@"G2"];
});
// 并行队列
dispatch_queue_t conQueue = dispatch_queue_create("com.lanou3g.www.comQueue", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(conQueue, ^{
[self printNumber:@"G1"];
[self printNumber:@"G2"];
});
dispatch_async(conQueue, ^{
[self printNumber:@"G3"];
});
dispatch_async(conQueue, ^{
[self printNumber:@"G4"];
});
}
-(void)printNumber:(NSString *)name {
for (int i = 0; i <10; i++) {
// sleep(1);
NSLog(@"%d,当前线程%@",i,[NSThread currentThread]);
NSLog(@"%@",name);
}
}
//GCD
//在延迟的时间点
- (IBAction)didClickAfterButton:(id)sender {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW,(int64_t)(5 * NSEC_PER_SEC) ),dispatch_get_main_queue(), ^{
NSLog(@"等我5秒");
});
}
//重复执行
- (IBAction)didClickApplyButton:(id)sender {
dispatch_apply(10, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(size_t t) { //参数t要添加上
NSLog(@"我在重复,第%zu次",t);//因为设置的全局队列,是并行的,所以输出的次数并没有次序
});
}
//当一个分组执行结束,notifiy之中的才会执行
- (IBAction)didClickNotfyButton:(id)sender {
//创建分组标签
dispatch_group_t groupA = dispatch_group_create();
//使用分组
//创建队列
dispatch_queue_t muQueue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_CONCURRENT);
//将操作添加到队列,添加分组标签
dispatch_group_async(groupA, muQueue, ^{
[self printNumber:@"groupA"];
});
dispatch_group_async(groupA, muQueue, ^{
[self printNumber:@"groupAA"];
});
//notify
dispatch_group_notify(groupA, dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"groupA的都执行完成以后,我才能执行");
});
}
//10.20 barrier线程执行时,其他线程不执行
- (IBAction)didClickBarrierButton:(id)sender {
//创建队列
dispatch_queue_t muQueue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_CONCURRENT);
//将操作添加到队列,添加分组标签
dispatch_async( muQueue, ^{
[self printNumber:@"opA"];
});
dispatch_async(muQueue, ^{
[self printNumber:@"opB"];
});
//将任务添加到队列中 此任务执行是,其他任务停止执行
dispatch_barrier_async(muQueue, ^{
[self printNumber:@"当我执行时,没人跟我抢"];
});
dispatch_async(muQueue, ^{
[self printNumber:@"opC"];
});
}
//声明单例 ,实现单例
static NSObject *object = nil;
- (IBAction)didclickOnceButton:(id)sender {
static dispatch_once_t onceToken;
// NSObject *objc = nil;
// __block NSObject *object = objc;
dispatch_once(&onceToken,^{ //once功能 整个程序运行期间,只走一次
object = [[NSObject alloc] init];
});
NSLog(@"%@",object);
}
//同步执行 10.20
- (IBAction)didClickSyncButton:(id)sender {
//同步线程里的内容不执行完成,下面的代码就不会执行
//如果放在主线程里,会阻塞线程 (主线程 diapatch_get_main_queue)
//GCD的方法比前两种多线程容易出错,但是效率高
dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{
NSLog(@"阻塞");
});
}
//将函数任务添加到队列
- (IBAction)didclickAsyncFButton:(id)sender {
dispatch_async_f(dispatch_get_main_queue(), nil, fun);
}
//输出 (上面的参数里需要一个c函数,这是一个c函数
void fun(){
int i = 10;
while (i > 0) {
printf("HAHAHHA ");
i--;
}
}
//
//使用NSObject加载图片,从子线程里下载,在主线程里更新
- (IBAction)didNsobjectLoadImageButton:(id)sender {
//NSObject进入子线程
[self performSelectorInBackground:@selector(loadImageUrl) withObject:nil];
}
-(void)loadImageUrl {
NSURL *url = [NSURL URLWithString:@"http://img3.douban.com/view/event_poster/median/public/10f53a2ad8b38c5.jpg"];
NSData *data = [[NSData alloc] initWithContentsOfURL:url];
UIImage *image = [[UIImage alloc] initWithData:data];
//返回主线程 更新UI
[self.imageView performSelectorOnMainThread:@selector(setImage:) withObject:image waitUntilDone:YES];//在子线程里下载图片,到主线程里去更新
}
//线程互斥
- (IBAction)ClickLockButton:(id)sender {
//创建线程锁
NSLock *lock = [[NSLock alloc] init];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
for (int i = 0; i < 50; i++) {
//加锁
[lock lock];
NSLog(@"小红买到了第%ld张票",self.count);
self.count--;
//解锁
[lock unlock];
}
});
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
for (int i = 0; i < 50; i++) {
//加锁
[lock lock];
NSLog(@"888绿买到了第%ld张票",self.count);
self.count--;
//解锁
[lock unlock];
}
});
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
//设置最大并发数
- (IBAction)dicclickMaxConButton:(UIButton *)sender {
//线程队列的最大并发数
NSInvocationOperation *iOP1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(printNumber) object:nil];
NSInvocationOperation *iOP2 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(printNumber) object:nil];
NSInvocationOperation *iOP3 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(printNumber) object:nil];
NSInvocationOperation *iOP4 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(printNumber) object:nil];
NSInvocationOperation *iOP5 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(printNumber) object:nil];
NSInvocationOperation *iOP6 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(printNumber) object:nil];
//添加到线程队列
[self.operationQueue addOperations:@[iOP1,iOP2,iOP3,iOP4,iOP5,iOP6] waitUntilFinished:YES];
}
//设置依赖关系
- (IBAction)didClickDependButton:(UIButton *)sender {
NSInvocationOperation *iOP1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(printNumber:) object:@"op1"];
NSInvocationOperation *iOP2 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(printNumber:) object:@"op2"];
NSInvocationOperation *iOP3 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(printNumber:) object:@"op3"];
//线程之间的依赖关系 必须等到被依赖的上一级线程全部执行完成之后,依赖的线程才能开始执行
[iOP1 addDependency:iOP2];
[iOP2 addDependency:iOP3];
[self.operationQueue addOperations:@[iOP1,iOP2,iOP3] waitUntilFinished:YES];
}
@end