OBJECT-C Programming Tips-timer

Source: Internet
Author: User

OBJECT-C Timer

OBJECT-C Timer will actively retain the current user, assuming that the call invalidate is not noticed, then very easy causes a circular reference to cause a memory leak. The following ideas provide a set of feasible solutions.


Example:

It is often possible to have the need to proactively refresh the interface in Viewcontroller. After the data has failed to get. It's a handy thing to use Nstimer every 10 seconds to refresh and retrieve data on your own initiative. Under normal circumstances, create a Nstimer repeat object directly, and then implement the corresponding Timerfiremethod method. This interface should be released when the user actively clicks back to the button. However, because Nstimer retain the current viewcontroller, it leads to interface memory leaks. You might say that you call invalidate in Dealloc, but you have to make sure that Dealloc is not called at all, and of course viewdiddisappear is not called.


A period of time ago looked at effective Object-c, learned a very good idea, is now shared out.

Add a category to Nstimer and use block to pass Timerfiremethod. The code is as follows:

@implementation Nstimer (lpblocks) + (nstimer*) lpscheduletimerwithtimerinternal: (nstimeinterval) interval                                       block :(void (^) ()) block                                     repeats: (BOOL) repeats{    return [self scheduledtimerwithtimeinterval:interval target:self Selector: @selector (lptimerblockinvoke:) userinfo:[block copy] repeats:repeats];} + (void) Lptimerblockinvoke: (nstimer*) timer{    void (^block) = Timer.userinfo;    if (block) {        block ();    }} @end

This Scheduledtimer method also retain target, but because this is a class method. It retains the class object, so there is no problem.

It passes in the block to be run, then gets the block through UserInfo in the callback function and runs.


Improved:

This is already a very big improvement. We are able to pass in the block code with confidence in the code. Just think carefully. Assume that the Viewcontroller member is introduced into the block, and that the timer is also present as a member variable in Viewcontroller.

For example, the following code:

@interface Lpnextviewcontroller () {    nstimer*  refreshtimer;}

In this way Viewcontroller and Refreshtimer are trapped in the logical circle of circular references. Of course you can avoid circular references by using weak_self in blocks, but it's always a bit uncomfortable to write code. It is also necessary for external users to do so explicitly.

So very easy to think. Should be encapsulated in a specialized Lptimer class. It is responsible for holding Nstimer. At the same time, the Nstimer block uses Lptimer's weak version number.

@interface Lptimer () {    nstimer* _polltimer;    Timer selector    __weak ID _weak_target;    SEL _selector;    ID  _userinfo;} @end

-(void) Scheduletimerwithtimerinternal: (nstimeinterval) Interval                                 target: (ID) Target                               selector: (SEL) Aselector                               UserInfo: (ID) userInfo                                repeats: (BOOL) repeats{    __weak id weak_self = self;    _weak_target = target;    _selector = Aselector;    _userinfo = UserInfo;    The block idea of borrowing the first version number    //using a second layer of indirection, calls _weak_target's Aselector method.    //This allows the Stoptimer to be encapsulated in. The outside does not need to manage the stop of the timer.    _polltimer = [Nstimer lpscheduletimerwithtimerinternal:1 block:^{        [weak_self Dotimer];    } repeats: Repeats];}

The above code Lptimer holds the Nstimer object. The block used by Nstimer is weak_self.

It calls its own Dotimer method when the timer triggers. In Dotimer, you are responsible for passing methods to external users.

-(void) dotimer{    if ([_weak_target Respondstoselector:_selector]) {        [_weak_target performselector:_selector Withobject:self];    }    else{        DLog (@ "Warnning:unknown selector");}    }


_weak_target is a user of external use. External users can consider Lptimer as an ordinary object, and there is no problem in holding it. Lptimer retains a weak reference to the external consumer. When the timer is triggered, it is first transferred to the Nstimer block. It is then passed to the dotimer of Lptimer. It is then called into the selector of _weak_target.


You must pay attention to releasing the Nstimer object and calling Nstimer's Invalidate method when Lptimer is released.

-(void) stoptimer{    DLog (@ "");    [_polltimer invalidate];} -(void) dealloc{    [self stoptimer];    DLog (@ "");}


In fact. The user is using the Lptimer class, then should let Lptimer performance and Nstimer behave exactly the same, using the combination of the adapter mode can be easily done.


Summarize:

The main idea is that Nstimer will retain an object and now let it retain class objects.

When the time comes to trigger, it is triggered by the Nstimer class object into the block. It is then triggered into an external lptimer normal object.

In the ordinary object we are able to handle it freely. Use Weak_target to make lptimer weak references to external users, and to disconnect external users from Lptimer.

Use weak_self to disconnect Lptimer from the loop associated with Nstimer. Personally feel that the idea is good, there is a need to welcome the discussion.





OBJECT-C Programming Tips-timer

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.