事件处理:响应者链条
多线程总结下哈:
什么是进程?进程就是系统正在运行的一个程序。每个进程之间是独立的,每个进程都运行在其专用并受保护的内存空间内。
什么是线程?
- 一个应用程序想要执行任务,必定有线程(一个进程至少有一个线程)。
- 一个进程的所有任务都在线程中完成。
线程的串行 - 一个线程中的任务是串行的
- 如果要在一个线程中执行多个任务,只能一个一个按照顺序执行
- 同一个时间,一个线程只能执行一个任务
多线程
- CPU在同一时间只能处理一个线程
- 快速切换造成同时处理的假象
所以,如果线程过多,会造成CPU资源消耗过度;每条线程的执行频率降低,导致线程的执行效率下降;
iOS中主要开销包括:内核数据结构(1KB);栈空间(子线程是512KB,主线程是1MB(每个程序至少有一个线程,所以就是他了),也可以使用setStackSize:进行设置,但必须是4KB的倍数,最小为16KB);创建一个线程大概需要90毫秒的时间。
iOS的主线程:
- 显示/刷新UI界面
- 处理UI事件(点击事件、滚动事件、拖拽事件)
pthread
使用C,跨平台的
//创建线程
pthread_t thread;
pthread_create(&thread, NULL, run, NULL);
void *run(void *param)
{
NSLog(@"Current Thread : %@",[NSThread currentThread]);
return NULL;
}
NSThread
直接操作线程对象
- (void)nsthread
{
//创建 虽然这里是局部变量,但是要等到执行完之后才会销毁,可以通过将其子类化,查看dealloc来进行验证。
NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(nsthreadRun:) object:nil];
//启动
// [thread setStackSize:100];
//start 就是将线程放到可调度线程池里,这样CPU就会处理
[thread start];
//创建并直接启动
[NSThread detachNewThreadSelector:@selector(aa:) toTarget:self withObject:nil];
//还有一种方式 线程之间的通信
[self performSelectorInBackground:@selector(aa:) withObject:nil];
// self performSelectorOnMainThread:<#(nonnull SEL)#> withObject:<#(nullable id)#> waitUntilDone:<#(BOOL)#> modes:<#(nullable NSArray *)#>
//强制停止线程
[NSThread exit];
//这个是整个程序挂掉
exit(0);
}
- (void)nsthreadRun:(id)sender
{
/*!
@brief do something
*/
//如果还需要在跳转到主线程进行UI什么de
[self performSelectorOnMainThread:@selector(mainRun:) withObject:nil waitUntilDone:YES];
}
GCD
可充分利用多核。C语言开发。
NSOperation
基于GCD来实现的
多线程的安全隐患
- 资源共享,就是多个吸纳和那个可能会访问同一块资源(比如多个线程访问同一个对象、同一个变量、同一个文件)
加锁:
//加锁的方式 可用任何一个对象 如[[NSObject alloc]init]
@synchronized (self) {
}
或者
//加锁的方式
pthread_mutex_t lock;
pthread_mutex_init(&lock, NULL);
pthread_mutex_lock(&lock);
pthread_mutex_unlock(&lock);
pthread_mutex_trylock(&lock);
pthread_mutex_destroy(&lock);
还有
//加锁
NSLock *lock1 = [[NSLock alloc]init];
[lock1 lock];
[lock1 tryLock];
[lock1 unlock];
GCD中也有
@property(nonatomic,strong)dispatch_semaphore_t lock;
//注意lock不能声明为局部变量
_lock = dispatch_semaphore_create(1);
dispatch_semaphore_wait(_lock, DISPATCH_TIME_FOREVER);
dispatch_semaphore_signal(_lock);
原子核非原子属性
OC在定义属性时有nonatomic
和atomic
两种选择
- atomic:原子属性,为setter方法加锁(默认就是atomic)。线程安全,需要消耗大量的资源。
程序执行时间计算
CFTimeInterval time = CFAbsoluteTimeGetCurrent();
RunLoop
使用RunLoop来保住线程的命,又能让他一直做事情。
利用NSPort来实现线程之间的通信
NSPort;
NSMessagePort;
NSMachPort;
不太重要,知道就行。