多线程创建的几种方式:
//创建线程的第一种方式 NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run:) object:@"universe"]; [thread start]; [thread release]; //创建线程的第二种方式,NSThread类方法 [NSThread detachNewThreadSelector:@selector(run:) toTarget:self withObject:@"yuzhou"]; //创建线程的第三种方法 NSObject方法 [self performSelectorInBackground:@selector(run:) withObject:@"nsobject thread"]; //创建线程的第四种方式 NSOperationQueue *oprationQueue = [[NSOperationQueue alloc] init]; [oprationQueue addOperationWithBlock:^{ //这个block语句块在子线程中执行 NSLog(@"oprationQueue"); }]; [oprationQueue release]; //第五种创建线程的方式 NSOperationQueue *oprationQueue1 = [[NSOperationQueue alloc] init]; oprationQueue1.maxConcurrentOperationCount = 1;//指定池子的并发数 //NSOperation 相当于java中的runnable接口,继承自它的就相当一个任务 NSInvocationOperation *invation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(run:) object:@"invation"]; [oprationQueue1 addOperation:invation];//将任务添加到池子里面,可以给池子添加多个任务,并且指定它的并发数 [invation release]; //第二个任务 NSInvocationOperation *invation2 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(run2:) object:@"invocation2"]; invation2.queuePriority = NSOperationQueuePriorityHigh;//设置线程优先级 [oprationQueue1 addOperation:invation2]; [invation2 release]; [oprationQueue1 release]; //调用主线程,用来子线程和主线程交互,最后面的那个boolean参数,如果为yes就是等这个方法执行完了在执行后面的代码;如果为no的话,就是不管这个方法执行完了没有,接着往下走 [self performSelectorOnMainThread:@selector(onMain) withObject:self waitUntilDone:YES]; //---------------------GCD----------------------支持多核,高效率的多线程技术 //创建多线程第六种方式 dispatch_queue_t queue = dispatch_queue_create("name", NULL); //创建一个子线程 dispatch_async(queue, ^{ // 子线程code... .. NSLog(@"GCD多线程"); //回到主线程 dispatch_sync(dispatch_get_main_queue(), ^{//其实这个也是在子线程中执行的,只是把它放到了主线程的队列中 Boolean isMain = [NSThread isMainThread]; if (isMain) { NSLog(@"GCD主线程"); } }); }); self.window.backgroundColor = [UIColor whiteColor]; [self.window makeKeyAndVisible];
以上代码不知道摘抄了哪位大神的代码,谢得很不错,就收录了,看到了请谅解,谢谢;
多线程中的队列问题:
/* A B C D 4个任务,每个任务持续2秒钟, 希望 A B执行完毕 再执行 C D, C D 执行完毕 再执行别的 */ //queue:队列 --- 一辆公交车 //任务:-----人 人 放到车里, 任务队列 dispatch_queue_t queue = dispatch_get_global_queue(0, 0); //新建任务分组 dispatch_group_t groupQueue=dispatch_group_create(); //把任务分组异步执行 dispatch_group_async(groupQueue, queue, ^{ sleep(2); NSLog(@"A任务执行完毕,%@", [NSThread currentThread]); }); dispatch_group_async(groupQueue, queue, ^{ sleep(2); NSLog(@"B任务执行完毕,%@", [NSThread currentThread]); }); //监听groupQueue 队列中的任务都执行完毕 dispatch_group_notify(groupQueue, queue, ^{ NSLog(@"A 和 B任务都执行完毕了 %@", [NSThread currentThread]); // 再次创建新的队列, 把C 和D 放到新的 分组队列中 });
多线程中的单例:
/** 制作单例: */ /**在进程整个生命中,只初始化一次的变量,指针初始化完毕以后,就不会再变了,系统方法单例开头:shared current main standard */ + (id)sharedVC{ //static是静态变量,内存存储区域分两块:堆,栈; 理解为 栈 存对象(带*的), 堆存不带*的 //特殊情况: 如果想要把带* 存到堆, 要使用static声明 //进程创建的时候,会被CPU分配一个堆, 堆里面的东西不会被主动释放. 进程被关闭的时候 堆会被清空回收. static ViewController *vc = nil; //可以加锁解决 NSLock @syncronized(){} //下放代码 线程不安全 if (!vc) { sleep(1); NSLog(@"......%@",[NSThread currentThread]); vc = [ViewController new]; } //标准的 GCD提供的 线程安全的 单例写法 //dispatch_once 可以保证内部代码 在整个进程生命中,只会执行一次 static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ NSLog(@"...%@",[NSThread currentThread]); sleep(2); vc = [ViewController new]; }); //该方法写在初始化里面 //打印3次: 线程1 进入if, 等待1秒. 1秒的时间里,线程2,和3也进来了
//如GCD:所有加到主线程的队列,都是串行的 //NSOperation 没有串行 [[NSOperationQueue mainQueue] addOperation:op]; //新式写法 --- 使用block来创建操作/任务 NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{ for (int i = 0; i < 5; i ++) { NSLog(@"--- %@", [NSThread currentThread]); } //让op3 和op4 在多线程(非主)中 并行 NSOperationQueue *queue1 = [NSOperationQueue new]; [queue1 addOperation:op3]; [queue1 addOperation:op4]; //如果想要让代码在主队列里有序执行,需要依次添加 [[NSOperationQueue mainQueue] addOperation:op3]; [[NSOperationQueue mainQueue] addOperation:op4]; return; //添加return 可以保证下方代码不执行 //封装GCD 从C语法->OC语法, 基本上效率没差别 //先有马路 再造车 -> 车放到马路上跑 //创建 线程, 再创建 任务队列 ->任务队列放到线程中运行 //通过new方式创建的队列 会自动的在非主线程上运行,并行队列 //异步+并行 NSOperationQueue *queue = [NSOperationQueue new]; //创建任务, Operation:操作 NSInvocationOperation *op1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(printMinus) object:nil]; NSInvocationOperation *op2 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(printPlus) object:nil]; //操作放入队列中 //[queue addOperation:op1]; //[queue addOperation:op2]; //获取主线程队列,把任务加载主线程队列中. [[NSOperationQueue mainQueue] addOperation:op1]; [[NSOperationQueue mainQueue] addOperation:op2];