看了一堂公开课,自己小结一下:
Runloop:
内部有三个东东:(Source, Timer, Observer)
作用/本质:1.死循环 (为app 保活);
2.监听处理事件
Timer 理解:
#pragma runloop -- Timer 理解 () NSThread *theard = [[NSThread alloc] initWithBlock:^{ NSTimer *timer = [NSTimer timerWithTimeInterval:1.0 repeats:YES block:^(NSTimer * _Nonnull timer) { NSLog(@"--timer-thread:%@",[NSThread currentThread]); }]; [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes]; [[NSRunLoop currentRunLoop] run];//run这个子线程/添加死循环,保证这个子线程存活。 //线程声明周期:只和它的任务有关系,任务没了,线程就没了!!! }]; //开启线程 [theard start];
source 理解:
#pragma runloop -- source 理解 (GCD 定时器) dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)); dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, 1.0 * NSEC_PER_SEC, 0 * NSEC_PER_SEC); dispatch_source_set_event_handler(timer, ^{ NSLog(@"--GCD:%@",[NSThread currentThread]); }); //全局化timer,不然执行一次后就被销毁了, _timer = timer; dispatch_resume(_timer);
observer 理解:
#pragma runloop -- observer 理解 (CoreFundation 监听runloop 事件) //获取runloop CFRunLoopRef runloop = CFRunLoopGetCurrent(); //创建观察者 (creat, new, copy 都会去堆中开辟内存空间!!) CFRunLoopObserverRef observerRef = CFRunLoopObserverCreate(NULL, kCFRunLoopBeforeTimers, YES, runloop, &callback, NULL); //添加观察者 CFRunLoopAddObserver(runloop, observerRef, kCFRunLoopDefaultMode); //释放观察者 observerRef 结构体指针(不能使用free,free只会释放该指针指向的堆区A;所指向的堆区内部可能含有指针,指向其他的堆区域B,free造成B的无法释放,内存泄漏!!) // free(observerRef); CFRelease(observerRef);
其他知识点:
// 常用的一对方法: // malloc(<#size_t __size#>) 向硬件要一定大小的内存空间, // free(<#void *#>) 释放内存空间 //线程之间的通讯 // self performSelector:@selector(<#selector#>) onThread:<#(nonnull NSThread *)#> withObject:<#(nullable id)#> waitUntilDone:<#(BOOL)#> //退出线程 //[NSThread exit]; // UIKit 是线程安全的吗? 不安全 为了避免多线程访问,资源抢夺,用主线程刷新UI,不用消耗内存进行加锁
如有理解偏差,请不惜指教!