-、NSTimer定时精度
在实现一个坚实系统剪贴板变化当程序中,发现使用NSTimer精度达不到要求,类似当问题可以在stackoverflow中找到,如下:
经过查询文档之后,timer当触发是在runloop当循环中检查是否已经到达触发条件,如果没有到达,就在下一次循环中继续检查。因此NSTimer当精度受制与Runloop的循环时间,并且收到线程调度的影响,文档中说明是50~100ms,对于一般的应用可以满足。
二、更精确的Timer
在stackoverflow上面搜索如何获得更精确的timer之后,发现下面这种方式能解决一般问题,但是精度还是大于200ms,但是比NSTimer更稳定一些,当程序退到后台之后,仍旧能正常触发。
解决办法:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 |
//建立新线程[NSThread
detachNewThreadSelector:@selector(timer) toTarget:self
withObject:nil]; //make a new thread//在线程中使用NSdate进行判断- (void)timer { @autoreleasepool
{ NSDate
*startDate = [NSDate
date]; while
(YES) { usleep(10000); if([[NSDate
date] timeIntervalSinceDate:startDate] >= watch_interval) { startDate = [NSDate
date]; objc_msgSend(self,@selector(watchLoop),nil); } } }} |
这个方法仍然有弊端,可能是NSDate到更新间隔,导致200ms到间隔不能缩小。
三、更精确到定时器,如果想获得更精确到定时器,可以参考apple到这份文档,文档中不建议使用该定时器,除非特别需要。
链接:https://developer.apple.com/library/ios/technotes/tn2169/_index.html
四、监视定时器变化到代码
.h 文件
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 |
//// PastboardWatcher.h// PastboardWatcher//// Created by on 14-3-20.// Copyright (c) 2014年 master. All rights reserved.//#import <Foundation/Foundation.h>@protocol
PastboardWatcherDelegate;@interface
PastboardWatcher : NSObject+ (id)shanreInstance;- (void)registerObsever:(id<PastboardWatcherDelegate>)delegate;- (void)removeDelegate:(id<PastboardWatcherDelegate>)delegate;@end@protocol
PastboardWatcherDelegate <NSObject>- (void)generalPastboardDidChange;@end |
.m文件
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114 |
//// PastboardWatcher.m// PastboardWatcher//// Created by on 14-3-20.// Copyright (c) 2014年 master. All rights reserved.//#import <objc/message.h>#import "PastboardWatcher.h"static
const
NSTimeInterval
watch_interval = 0.2;@interface
PastboardWatcher ()@property
(nonatomic, strong) NSMutableArray
*obseverArray;@property
(nonatomic, assign) NSInteger
changeCount;@property
(nonatomic, strong) NSRecursiveLock
*lock;@end@implementation
PastboardWatcher+ (id)shanreInstance{ static
PastboardWatcher *instance = nil; static
dispatch_once_t once_token; dispatch_once(&once_token,^{ instance = [[PastboardWatcher alloc] init]; }); return
instance;}- (id)init{ if(self
= [super
init]) { _obseverArray = [[NSMutableArray
alloc] init]; _changeCount = [[NSPasteboard
generalPasteboard] changeCount]; _lock = [[NSRecursiveLock
alloc] init]; [NSThread
detachNewThreadSelector:@selector(timer) toTarget:self
withObject:nil]; //make a new thread } return
self;}- (void)registerObsever:(id<PastboardWatcherDelegate>)delegate{ [_lock lock]; [_obseverArray addObject:delegate]; [_lock unlock];}- (void)removeDelegate:(id<PastboardWatcherDelegate>)delegate{ [_lock lock]; NSInteger
findIndex = [_obseverArray indexOfObject:delegate]; if(findIndex != NSNotFound) [_obseverArray removeObjectAtIndex:findIndex]; [_lock unlock];}- (void)timer { @autoreleasepool
{ NSDate
*startDate = [NSDate
date]; while
(YES) { usleep(10000); if([[NSDate
date] timeIntervalSinceDate:startDate] >= watch_interval) { startDate = [NSDate
date]; objc_msgSend(self,@selector(watchLoop),nil); } } }}- (void)watchLoop{ NSInteger
current_changeCount = [NSPasteboard
generalPasteboard].changeCount; if(current_changeCount != _changeCount) { _changeCount = current_changeCount; objc_msgSend(self, @selector(notifyObseverChange),nil); }}- (void)notifyObseverChange{ [_lock lock]; NSArray
*tempArray = [_obseverArray copy]; [_lock unlock]; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ for
(id<PastboardWatcherDelegate> delegate in tempArray) { if([delegate respondsToSelector:@selector(generalPastboardDidChange)]) { objc_msgSend(delegate, @selector(generalPastboardDidChange)); } } });}@end |
高精度的Timer(Objetive C),布布扣,bubuko.com
原文:http://www.cnblogs.com/mystackflow/p/3614741.html