iOS进阶-03:多线程-01(NSThread)

一.多线程的实现方式

1.GCD(最为熟悉的方式,也是苹果内部实现所使用的方式)

2.NSThread(苹果推出的面向对象的线程操作,由于需要手动管理所以大多不被人使用)

3.NSOperationQueue(其核心本质是对于GCD多线程的一种封装)

二.优缺点

1.NSThread

优点:由于NSThread是面向对象的线程操作,而且所有操作都需要手动管理,所以NSThread的可控性非常高,对于事件的处理和对象线程的优先级设置都可以完美的实现。并且所有线程操作的开启与关闭都是自主手动控制,对于项目的实现流程可以有很好的把控性。

缺点:同样由于NSThread的所有操作都需要人为手动控制,对于开发者对其使用的掌控能力要求较高,代码量同样也会增加。

2.GCD

优点:通过dispatch函数来手动创建主队列和子队列,可以用于多种核心的操作 (单核多线层、多核多线程等的操作),起代码创建队列含义明确能迅速主观的了解代码含义,并且还可以通过dispatch函数来实现队列间的数据传输。对于队列中的操作也有明确的处理属性。

缺点:由于GCD 的实现都是通过dispatch函数来创建,对于代码的熟知程度要求较高,要求开发者的细致性较高,对于队列线程的使用时极容易造成线程的卡顿,对于主/子线程事件的分配要求明确否则会出现资源卡顿以及内存资源过度消耗。对于线程间的通信要求必须使用对应的线程锁 否则会导致野指针产生崩溃的问题。而且GCD的实现逻辑可以通过group操作来实现大量线程组的操作,如果不同队列间有相互依赖的事件,那队列组之间的事件优先级需要手动设置。

3.NSOperationQueue

优点:NSOperationQueue是基于GCD的一层高级封装,其内部核心实现就是通过GCD完成的,所以NSOperationQueue继承了GCD的所有有点,并且NSOperationQueue其本身就是队列组性质的多线程事件,直接通过添加队列事件来实现多线程的操作就可以,并且能够直接添加队列间的相互依托关系。可以通过调整队列的权重来设置队列的优先级,而且也可以手动停止某一队列。

缺点:由于NSOperationQueue是基于GCD的封装,其代码的可读性和对于开发者的技术要求较高,代码的易读性较差。

三.多线程的实现及使用

1.NSThread

初始化

/** 三种初始化方式都需要手动实现线程的开启或者关闭 */    

/** 通过事件绑定创建多线程事件 */   

NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(newThread) object:nil];   

/** 初始化NSThread对象手动添加多线程事件 */   

NSThread *thread1 = [[NSThread alloc] init];   

/** 通过block实现多线程操作 */   

NSThread *thread2 = [[NSThread alloc] initWithBlock:^{        

//需要注意这个block中不能直接使用实例化对象thread2,在这个block中它还未被实例化完成。

}];

线程属性

/** 通过此线程属性字典添加的键值对在当前线程的任何位置都是可以直接访问并且能够保持其唯一性(未被修改过键值属性) */    [thread2.threadDictionary setValue:@"value" forKey:@"key"];   

/** 优先级 */   

thread2.threadPriority = 1;       

/** 线程优先级 */   

/**    

NSQualityOfServiceUserInteractive,最高优先级    

NSQualityOfServiceUserInitiated,较高优先级    

NSQualityOfServiceUtility,普通优先级    

NSQualityOfServiceBackground,最低等优先级    

NSQualityOfServiceDefault   默认优先级         

最低等<默认<普通<较高<最高    

当qualityOfService被设置后 threadPriority这一属性默认失效.    

*/   

thread2.qualityOfService = NSQualityOfServiceDefault;

/** 设置线程名 */   

thread2.name = @"mainThread";       

/**    

获取线程在栈区内存大小(大小为字节数B 而不是KB)    

需要注意 苹果内置字节计算大小是1000进制,但是开发中要严格按照1024执行.    

*/   

NSLog(@"%ld",thread2.stackSize/1024);

/** 开启线程 ,此方法不是线程属性 为线程的实例方法*/   

[thread2 start];

实例方法

/**    

是否结束    

Bool类型直接使用整数占位符打印 OC原则非0即为真所以 打印结果只要不是0就是yes反之则为no    

*/       

NSLog(@"%d",[thread2 isFinished]);   

/**     是否可取消     */   

NSLog(@"%d",[thread2 isCancelled]);   

/**     是否正在执行    */   

NSLog(@"%d",[thread2 isExecuting]);

/**是否为主线程*/   

NSLog(@"%d",[thread2 isMainThread]);       

/** 设置线程名称 */   

[thread2 setName:@"mainThread"];       

/** 取消线程 */   

[thread2 cancel];

类方法

/** 创建线程的两种类方法(不用调用实例方法start 内部默认启动) */   

[NSThread detachNewThreadWithBlock:^{

        NSLog(@"111");   

}];       

[NSThread detachNewThreadSelector:@selector(log) toTarget:self withObject:nil];

-(void)log{

    NSLog(@"222");

}

/** 设置线程休眠的两的方式 */       

[NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:2.0]];       

[NSThread sleepForTimeInterval:2.0];

/** NSThread最常用的类方法 获取当前线程 */   

NSLog(@"%@",[NSThread currentThread]);   

/** 是否是在主线程上 */   

NSLog(@"%d",[NSThread isMainThread]);

 /** 退出线程 */       

[NSThread exit];

下一节介绍NSThread线程间的互相通信和常用的线程锁。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

想你知道

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值