一偎痛、NSTimer
創(chuàng)建方式
a.這種方式創(chuàng)建的定時(shí)器谓谦,在哪個(gè)縣城中創(chuàng)建加到哪個(gè)線程
_timer= [NSTimer scheduledTimerWithTimeInterval:1target:selfselector:@selector(changed) userInfo:nil repeats:YES];
b.該方法創(chuàng)建的NSTimer需要手動(dòng)添加到RunLoop中
_timer = [NSTimer timerWithTimeInterval:1 ?target:self ?selector:@selector(chagned) ?userInfo:nil ?repeats:YES];
注:若不加入到主線程中,定時(shí)器是不會(huì)啟動(dòng)的
[[NSRunLoop currentRunLoop] addTimer:_timer forMode:NSRunLoopCommonModes];
注意:
a.當(dāng)在一個(gè)控制器中Push到下個(gè)界面优质,而下一個(gè)界面有NSTimer定時(shí)器時(shí)爷耀,是會(huì)有內(nèi)存泄漏的,所有務(wù)必要進(jìn)行銷毀萨螺,通常的做法是在- (void)viewDidDisappear:(BOOL)animated
是銷毀定時(shí)器
通過dealloc即可以發(fā)現(xiàn)有沒有銷毀
b.當(dāng)NSTimer 加入到了滾動(dòng)視圖上吻商,當(dāng)滾動(dòng)視圖的時(shí)候枉昏,可能會(huì)出現(xiàn)定時(shí)器不走的情況,典型的就是tabview中cell嵌套了Scrollview 即廣告欄蛔外,當(dāng)在滾動(dòng)tabview時(shí)溯乒,廣告欄圖片不自動(dòng)進(jìn)行輪播了,處理方法如下:
b.1 將定時(shí)器加入到CurrentRunLoop中的CommonModel或者TrackingModel
[[NSRunLoop currentRunLoop] addTimer:_timer forMode:UITrackingRunLoopMode];
b.2利用線程的方式解決NSTime不執(zhí)行的問題
開一個(gè)線程
[NSThread detachNewThreadSelector:@selector(thread) toTarget:selfwithObject:nil];
在線程的響應(yīng)方法中執(zhí)行
- (void)thread
{
_timer= [NSTimer ?scheduledTimerWithTimeInterval:1 ?target:self selector:@selector(chagned) ?userInfo:nil ?repeats:YES];
//讓子線程的RunLoop開啟
[[NSRunLoopcurrent RunLoop] run];
}
//RunLoop的三種模式
// NSDefaultRunLoopMode默認(rèn)
// NSRunLoopCommonModes通用模式
// UITrackingRunLoopMode UI事件傳入模式(用戶的點(diǎn)擊,拖動(dòng)等)
定時(shí)器的相關(guān)方法
a.暫停定時(shí)器
[_timer setFireDate:[NSDate distantFuture]];
b.開始定時(shí)器
[_timersetFireDate:[NSDate distantPast]];
c.銷毀定時(shí)器
[_timer ?invalidate];
_timer=nil;// 一般是一起用(_timer = nil)
二、CADisplayLink
CADisplayLink 同屏幕的刷新率伴奥,一般屏幕的默認(rèn)刷新次數(shù)為60/s
使用方式
_displayLink = [CADisplayLink displayLinkWithTarget:selfselector:@selector(update)];
//修改刷新頻率,多少幀刷新一次
_displayLink.frameInterval =60;
//銷毀
//??? [_displayLink invalidate];
//??? _displayLink = nil;
//當(dāng)添加到RunLoop中會(huì)立即執(zhí)行
[_displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
是否 暫停定時(shí)器
_displayLink.paused=YES;
三雌续、GCD的方式
__blockintj =0;
//第三種創(chuàng)建方式:
timer=dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER,0,0,dispatch_get_main_queue());
// intervarlInSeconds每隔多久執(zhí)行一次
// leewayInSeconds允許出現(xiàn)多少誤差,0為最精準(zhǔn)
dispatch_source_set_timer(timer,DISPATCH_TIME_NOW,1*NSEC_PER_SEC,0*NSEC_PER_SEC);
//執(zhí)行的事件
dispatch_source_set_event_handler(timer, ^{
NSLog(@"%d", j++);
});
//執(zhí)行
dispatch_resume(timer);
//停止
//??? dispatch_source_cancel(timer);
Run loop是和線程緊密相關(guān)的非常重要的基礎(chǔ)冲九。一個(gè)Run loop就是一個(gè)事件處理循環(huán)谤草,可用于調(diào)度,協(xié)調(diào)輸入事件的接收莺奸。Run loop是自動(dòng)管理的丑孩。他的作用就是循環(huán)、處理事件灭贷。
runloop基本作用
1.保持程序的持續(xù)運(yùn)行
2.處理app的各種事件(比如觸摸事件温学,定時(shí)器事件,selector事件)
3.節(jié)省CPU資源甚疟,提高程序性能仗岖。
RunLoop的用處
1.解決NSTimer滑動(dòng)視圖時(shí),定時(shí)器暫停的問題
2.解決單滑動(dòng)ScrollView時(shí)NSURLConnection代理不執(zhí)行的問題
eg:下載數(shù)據(jù)時(shí)滑動(dòng)滾動(dòng)視圖進(jìn)度條不走览妖,不滑動(dòng)時(shí)轧拄,有繼續(xù)走
解決方案
a.將方法NSURLConnection *connection = [NSURLConnection connectionWithRequest:request delegate:self];換成
NSURLConnection*connection = [[NSURLConnectionalloc]initWithRequest:requestdelegate:selfstartImmediately:NO];// 注:這里的是否立即執(zhí)行應(yīng)該選擇NO,否則讽膏,下面就沒辦法馬上添加到CommonModel中了
b.將connection添加到NSRunLoopCommonModes模式下
[connectionscheduleInRunLoop:[NSRunLoopcurrentRunLoop]forMode:NSRunLoopCommonModes];
[connectionstart]; //開始連接
完整代碼如下
@interfaceViewController()
//解決當(dāng)滑動(dòng)ScrollView時(shí)NSURLConnection代理不執(zhí)行的問題
NSURL*url = [NSURLURLWithString:@"http://dl_dir.qq.com/qqfile/qq/QQforMac/QQ_V2.4.1.dmg"];
NSURLRequest*request = [NSURLRequestrequestWithURL:url];
//??? NSURLConnection *connection = [NSURLConnection connectionWithRequest:request delegate:self];
NSURLConnection*connection = [[NSURLConnectionalloc]initWithRequest:requestdelegate:selfstartImmediately:NO];
//將connection添加到RunLoop中檩电,并設(shè)置模式
[connectionscheduleInRunLoop:[NSRunLoopcurrentRunLoop]forMode:NSRunLoopCommonModes];
[connectionstart];
#pragma mark - NSURLConnectionDataDelegate
- (void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data
{
NSLog(@"%ld", data.length);
}
- (void)connectionDidFinishLoading:(NSURLConnection*)connection
{
NSLog(@"下載完成!");
}