本篇文章主要介绍了"UI多线程、开辟方式及线程安全",主要涉及到方面的内容,对于IOS开发感兴趣的同学可以参考一下:
1.多线程的简介进程:是操作系统的基础,是一次程序的执行,是操作系统动态执行的基本单元,在传统的操作系统中,进程是基本的分配单元,也是基本执行单元。线程:有时被...
1.多线程的简介
进程:
是操作系统的基础,是一次程序的执行,是操作系统动态执行的基本单元,
在传统的操作系统中,进程是基本的分配单元,也是基本执行单元。
线程:
有时被称为轻量进程,是进程执行流中的最小单元;
iOS程序中默认只有一个线程,也就是主线程,所有的用户交互、界面刷新都必须在主线程中进行。
若再主线程中执行复杂长时间的操作,会阻塞主线程(程序无响应等),大大降低用户体验;可以通过开启后台线程来执行这些操作,保持主线程流畅,避免这类问题的发生。
在主线程中调方法可能会堵塞主线程,因此开辟子线程可以避免此类现象。
一般不会去开辟多线程 如异步网络请求 它会会自动开辟线程去完成
不用专门去开辟2.
线程开辟方式代码示例:
方法一://NSObject的类目
[self performSelectorInBackground:@selector(logOneToHundred) withObject:nil];
//后台调用某个方法
//打印1-99 和打印@“打印完毕”同时进行 完成之后交给主线程与界面进行交互(谁先完成就先给主线程交互)方法二:NSThread 线程方法//类方法
[NSThread detachNewThreadSelector:@selector(logOneToHundred) toTarget:self withObject:nil];
方法三:NSThread 线程方法//示例方法
NSThread * thread = [[NSThread alloc]initWithTarget:self selector:@selector(getImageWithUrl) object:nil];
[thread start];
方法四:NSOperationQueue 队列方法(用于多网络请求管理) NSOperation 类似于UIController
第一步:初始化队列
//初始化操作队列--让block方法执行 _operationQueue = [[NSOperationQueue alloc] init];
第二步:用block方法调用方法
NSOperation * blockOperation = [NSBlockOperation blockOperationWithBlock:^{
//这个Block中写入 开辟线程用 来做什么的
[self getImageWithUrl];
}];
[blockOperation setCompletionBlock:^{
//这个block中写入 线程执行完毕后 的操作。。。 [self performSelectorOnMainThread:@selector(updateUI) withObject:nil waitUntilDone:NO];
}];
第三步:将block方法放入声明的队列中
//注意?:NSOperation的子类实例对象必须放到操作队列中执行 [_operationQueue addOperation:blockOperation];
方法五:NSOperationQueue 队列方法(用于多网络请求管理)NSOperation子类的方法
第一步:声明子类对象,调用方法
NSInvocationOperation * invocationOperation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(getImageWithUrl) object:nil];
第二步:用block方法调方法
[invocationOperation setCompletionBlock:^{
[self performSelectorOnMainThread:@selector(updateUI) withObject:nil waitUntilDone:NO];
}];
第三步:将block方法放入声明的队列中
[_operationQueue addOperation:invocationOperation];
方法五:自定义NSOperation子类方法
第一步:创建一个继承于NSOperation的自定义类 command + N .h文件中
#import
@interface CustomOperation : NSOperation
- (void)main;//重写耗时较长的方法
@end
第二步:重写main方法 .m文件中
#import "CustomOperation.h"
@implementation CustomOperation
- (void)main{//重写耗时较长的方法
//当前线程耗时三秒的操作
[NSThread sleepForTimeInterval:3];
}
@end
第三步:声明子类对象,调用方法
CustomOperation * customOperation = [[CustomOperation alloc] init];
第四步:用block方法调方法
[customOperation setCompletionBlock:^{
[self performSelectorOnMainThread:@selector(updateLableWithString:) withObject:@"123"waitUntilDone:NO];
}];
第五步:将block方法放入声明的队列中
[_operationQueue addOperation:customOperation];
方法六:GCD方法
//创建一个并行队列 dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//异步执行队列
dispatch_async(globalQueue, ^{
//开辟的线程用来干什么。。。 [self getImageWithUrl];
//执行一个主队列
dispatch_async(dispatch_get_main_queue(), ^{
//刷新界面
[self performSelectorOnMainThread:@selector(updateUI) withObject:nil waitUntilDone:NO];
});
});
3.线程安全—线程锁
当多个线程同时访问一个资源时,会出现线程安全(数据、变量)问题:
UIKit中的所有对象默认都是非线程安全的、需要在主线程刷新UI界面元素
iOS中保证变量线程安全的方法:
(1)atomic特性属性声明
(2)@synchronized关键字
(3)NSLock线程锁
代码示例:
第一步:在接口文件声明[全局变量或属性均可]
NSInteger _count;//验证线程安全
NSLock * _lock;//线程锁
第二步:初始化线锁
_lock = [[NSLock alloc]init];//初始化
第三步:
[NSThread detachNewThreadSelector:@selector(upCount) toTarget:self withObject:nil];
[NSThread detachNewThreadSelector:@selector(downCount) toTarget:self withObject:nil];
- (void)upCount{
while (1) {
// //方法一:
// //保护成员变量每次只能被一个线程访问// @synchronized(self){
// NSLog(@"%ld", _count +=1);
// }
//方法二:
[_lock lock];//上锁
NSLog(@"%ld", _count +=1);
[_lock unlock];//解锁
}
}
- (void)downCount{
while (1) {
// //保护成员变量每次只能被一个线程访问// @synchronized(self){
// NSLog(@"%ld", _count -=1);
// }
//方法二:
[_lock lock];//上锁
NSLog(@"%ld", _count -=1);
[_lock unlock];//解锁
}
}
以上就介绍了UI多线程、开辟方式及线程安全,包括了方面的内容,希望对IOS开发有兴趣的朋友有所帮助。
本文网址链接:http://www.codes51.com/article/detail_109421.html