MSWeakTimer
简易翻译:该timer没有runloop概念,线程安全,没有循环引用现象。
https://github.com/mindsnacks/MSWeakTimer
Description
Thread-safe NSTimer
drop-in alternative that doesn't retain the target and supports being used with GCD
queues.
这是个线程安全的 NSTimer,他不会对目标进行retain操作,而且,他还支持GCDqueues。
Motivation
The first motivation for this class was to have a type of timer that objects could own and retain, without this creating a retain cycle ( like NSTimer
causes, since it retains its target ). This way you can just release the timer in the -dealloc
method of the object class that owns the timer.
写这个类的动机是,我想使用这样的NSTimer,他不会对object进行retain操作,而且,更不会出现循环引用(系统的NSTimer就会出现这个问题)。然后呢,你可以在-dealloc方法中来释放这个timer。
The other problem when using NSTimer
is this note on the documentation:
另一个使用NSTimer会出现的问题在以下文档中提出了:
Special Considerations
You must send this message from the thread on which the timer was installed. If you send this message from another thread, the input source associated with the timer may not be removed from its run loop, which could prevent the thread from exiting properly.
需要特别注意的地方
你必须在当前的线程中给你创建的NSTimer发送信息,如果你是从另外一个线程中发过来的信息,那么,这个timer可能就不会从他当前的run loop中移除,那个会很出现问题的。
More often than not, an object needs to create a timer and invalidate it when a certain event occurs. However, doing this when that object works with a private GCD
queue gets tricky. This timer object is thread safe and doesn't have the notion of run loop, so it can be used with GCD
queues and installed / invalidated from any thread or queue.
不管怎样,一个对象创建出一个定时器,当触发了几次事件后,就销毁这个定时器。然而,你如果在GCD队列中来销毁这个定时器,效果非常微妙(有可能出现内存泄露)。而大哥我写的这个定时器是线程安全的,他不存在run loop的概念,所以,他可以在任何的GCDqueue中进行初始化以及移除掉。
Related Stackoverflow question.
Implementation
The implementation of MSWeakTimer
was reviewed and validated by a libdispatch
(GCD
) engineer at the WWDC 2013 Core OS Lab.
How to Use
Create an MSWeakTimer
object with this class method:
+ (MSWeakTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)timeInterval target:(id)target selector:(SEL)selector userInfo:(id)userInfo repeats:(BOOL)repeats dispatchQueue:(dispatch_queue_t)dispatchQueue;