When multiple timers are implemented on the page, choose NSTimer or GCD? (Dry goods are not wet), nstimergcd

Source: Internet
Author: User

When multiple timers are implemented on the page, choose NSTimer or GCD? (Dry goods are not wet), nstimergcd

The timer is essential for every iOS project, such as the logon page countdown and payment period countdown. Generally, NSTimer is used to create the Timer:

+ (NSTimer *) timerWithTimeInterval :( NSTimeInterval) ti target :( id) aTarget selector :( SEL) aSelector userInfo :( nullable id) userInfo repeats :( BOOL) yesOrNo;

+ (NSTimer *) scheduledTimerWithTimeInterval :( NSTimeInterval) ti target :( id) aTarget selector :( SEL) aSelector userInfo :( nullable id) userInfo repeats :( BOOL) yesOrNo;

ButNote the following points when using NSTimer:

1. Make sure there is an active RunLoop.

The system framework provides several methods to create NSTimer. The method starting with scheduled automatically adds timer to the current RunLoop, And the selector method is triggered at the specified time, the method without the start of scheduled requires you to manually add the timer to a RunLoop. When the program starts, the main thread's RunLoop is started by default and is valid during the running period. Therefore, when timer is put into the main thread, RunLoop does not need to be started, however, in actual development, the main thread processes more UI things and places time-consuming and energy-consuming operations in the Child thread. This requires the RunLoop of the child thread to be activated.

It is not hard to know that RunLoop generally has two types at run time: NSDefaultRunLoopMode and NSEventTrackingRunLoopMode. The timer generated by scheduled is added to NSDefaultRunLoopMode by default. When some UI events occur, such as page sliding, we will find that the timer is invalid. To solve the problem of timer failure, we need to set its running mode:

[[Nsunloop currentRunLoop] addTimer: self. progressTimer forMode: nsunloopcommonmodes];

Note: nsunloopcommonmodes is not an existing running state. This mode is equivalent to the combination of NSDefaultRunLoopMode and NSEventTrackingRunLoopMode, and is equivalent to marking timer in both modes.

2. NSTimer creation and revocation must be performed in the same thread and cannot be performed across threads.

3. There is a risk of Memory leakage (this issue needs to be taken seriously)

When the scheduledTimerWithTimeInterval method sets target as A object, object A will be held by this timer, that is, it will be retain once, and the timer will be held by the current runloop. When NSTimer is used, timer keeps a strong reference to the target and userInfo parameters. The target and userInfo of nstdate will be released only when the invalidate method of NSTimer is obtained. If the repeats parameter is NO in the timer generation method, the invalidate method is automatically called after the timer is triggered. If the repeats parameter is YES, you must manually call the invalidate method to release the strong reference of timer to target and userIfo.

-(Void) cancel {

[_ Timer invalidate];

_ Timer = nil;

}

Note that most of the objects we destroy or release are in the dealloc method, as shown in various materials. Then we are happy to write in dealloc

-(Void) dealloc {

[Self cancel];

}

In this way, the timer can be released. Unfortunately, the dealloc method will never be called. Because timer references, the reference count of object A will never be reduced to 0. If cancel is not called, object X will never be released, causing memory leakage.Therefore, it is recommended that timer be cancel immediately after the timer event is completed. If it is a long timer, it can be called in the page disappear eventSuch:

-(Void) viewWillDisappear :( BOOL) animated {

[Super viewWillDisappear: animated];

[Self cancel];

}

If you see this, will you find it So troublesome to use NSTimer to implement the timer? It's a RunLoop and a thread. You have to consider Memory leakage later. So, if multiple timers need to be displayed on a page at the same time, nst is a disaster. Is there any way to achieve this? The answer is GCD! The following five points are the main knowledge points for using dispatch_source_t to create a timer:

1. Obtain the global subthread queue

Dispatch_queue_t queue = dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0 );

2. Create a timer and add it to the queue.

Dispatch_source_t timer = dispatch_source_create (DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue );

3. Set the first execution event, execution interval, and accuracy

Dispatch_source_set_timer (timer, dispatch_time (DISPATCH_TIME_NOW, interval * NSEC_PER_SEC), interval * NSEC_PER_SEC, 0.1 * NSEC_PER_SEC );

4. process the event block

Dispatch_source_set_event_handler (timer, ^ {

// DoSomething ()

});

5. Activate/cancel timer

Dispatch_resume (timer);/dispatch_source_cancel (timer );

Here, I naturally want to ask what if I just want to execute it once and don't need to implement the timer cyclically? There is No problem either. For details, refer to NSTimer. we can integrate the repeats option. When repeats = No, after the timer is activated and the block event is called back, dispatch_source_cancel will drop the current dispatch_source_t timer:

The above Code creates a timer. If repeats = NO, after a cycle is completed, the system automatically cancel the timer; If repeats = YES, then, timer will execute the timer one by one cycle until you manually delete the timer, You can do cancel in the dealloc method, so that timer runs in the entire object lifecycle. There is no need to worry about the memory leakage caused by nstloc because dealloc is always unable to be called. You can also control the thread added to the timer through the queue parameter, that is, the thread of the final execution of the action. When nil is passed in, it is put into the Child thread for execution by default. UI-related operations must be passed in dispatch_get_main_queue () to be executed in the main thread.

Here, we can basically meet the development requirements, but we can be more abnormal. Assume that in this scenario, before each start of a new timer, you need to cancel the previous timing task or merge the previous timing task into a new timing task, and finally execute it together! These two scenarios have also been integrated into the above interface scheduleGCDTimerWithName. For specific code, see the demo!

Github address: https://github.com/BeckWang0912/ZTGCDTimer

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.