多线程创建的几种方式:
//创建线程的第一种方式
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];