Explore Runloop (ii) (Runloop self-fulfilling runloop)

Source: Internet
Author: User
Tags uikit

Now that you've learned from the previous article how Runloop works. It is also possible to do it yourself. This article code more, carefully read the code to understand there will be a harvest. At the end

There will be some clarification.

The demo used in this article is the Simplerunloop on my GitHub.

   First Runloop that must have an event input source. Create a class for a timed input source Simpletimer:

#import <Foundation/Foundation.h>#import <UIKit/UIKit.h>@interface  Simpletimer:nsobject+ (Simpletimer *) Scheduledtimerwithtimerinterval: (cgfloat) interal target: (ID target selector: (SEL) Selector repeat: (BOOL) repeat; @end
#import <Foundation/Foundation.h>#import"SimpleTimer.h"@ InterfaceID  target; @property (nonatomic, assign) SEL action; @property (nonatomic, assign) Cfabsolutetime lasttime; @property (nonatomic, assign) cgfloat interval; @property (nonatomic, assign) BOOL isrepeat; -(void) invoke; @end
#import "SimpleTimer.h"#import "SimpleTimerPrivate.h"@implementationSimpletimer+ (Simpletimer *) Scheduledtimerwithtimerinterval: (cgfloat) interal target: (IDtarget selector: (SEL) Selector repeat: (BOOL) repeat; {Simpletimer*timer =[[Simpletimer alloc] init]; Timer.target=Target; Timer.action=selector; Timer.interval=interal; Timer.lasttime=cfabsolutetimegetcurrent (); Timer.isrepeat=repeat; returntimer;}- (void) invoke{//Remove the warning#pragmaClang Diagnostic push#pragmaClang diagnostic ignored "-warc-performselector-leaks"if([Self.target respondsToSelector:self.action]) {[Self.target performSelector:self.action withobject:nil]; }#pragmaClang Diagnostic Pop}@end

Next is the Runloop,simplerunloop class that is called when the event is received:

#import <Foundation/Foundation.h>@class  simpletimer; @interface simplerunloop:nsobject-(void) AddTimer: (Simpletimer *) timer; -(void) Rununtildate: (NSDate *) limitdate; @end
#import "SimpleRunLoop.h"#import "SimpleTimerPrivate.h"@interfaceSimplerunloop () {Nsmutablearray<simpletimer *> *_timerqueue;}@end@implementationSimplerunloop- (ID) init{ Self=[Super Init]; if(self) {_timerqueue= [Nsmutablearray<simpletimer *>array]; }    returnSelf ;}- (void) Rununtildate: (NSDate *) limitdate{BOOL finish=NO;  while(!finish) {Usleep (2* +);//Tow Second[self executeonce]; NSDate*date =[NSDate Date]; if([date compare:limitdate] = =nsordereddescending) {Finish=YES; }    }}- (void) AddTimer: (Simpletimer *) timer{[_timerqueue Addobject:timer];}- (void) executeonce{cfabsolutetime currenttime=cfabsolutetimegetcurrent (); Nsmutablearray<simpletimer *> *temptodeletearray = [Nsmutablearray<simpletimer *>array]; Nsmutablearray<simpletimer *> *enumarray =[_timerqueue copy];  for(Simpletimer *timerinchEnumarray) {        if(Currenttime-timer.lasttime >=timer.interval) {if(timer.isrepeat) {timer.lasttime=currenttime; }            Else{[Temptodeletearray addobject:timer];        } [timer invoke]; }} [_timerqueue Removeobjectsinarray:temptodeletearray];}@end

Think again, nsrunloop each thread will only have one, then to achieve this, I added a nsthread (Simplerunloop) class.

#import <Foundation/Foundation.h>#import"SimpleRunLoop.h" @interface Nsthread (Simplerunloop)+ (Simplerunloop *) Currentsimplerunloop; @end
@implementationNsthread (Simplerunloop)+ (Simplerunloop *) Currentsimplerunloop; {Simplerunloop*simplerunloop =Nil; Nsthread*currentthread =[Nsthread CurrentThread]; Static Const void*ksimplehashkey = &Ksimplehashkey; Simplerunloop=Objc_getassociatedobject (CurrentThread, Ksimplehashkey); if(!Simplerunloop) {Simplerunloop=[[Simplerunloop alloc] init];    Objc_setassociatedobject (CurrentThread, Ksimplehashkey, Simplerunloop, objc_association_retain_nonatomic); }        returnSimplerunloop;}@end

Paste so much code, always talk about how to call it, the following is the way to use, want to know what to print the demo down to run a bit to know.

@implementationViewcontroller- (void) viewdidload {[Super viewdidload]; //additional setup after loading the view, typically from a nib.NSLog (@"Viewdidload begin"); //Create a input sourceSimpletimer *timer = [Simpletimer scheduledtimerwithtimerinterval:2target:self selector: @selector (timerfire:) Repeat:yes]; //add input source to RunloopSimplerunloop *simplerunloop =[Nsthread Currentsimplerunloop];        [Simplerunloop Addtimer:timer]; //begin the Runloop[Simplerunloop rununtildate:[nsdate Datewithtimeintervalsincenow:Ten]];//Run Ten secondNSLog (@"Viewdidload End");}- (void) Timerfire: (Nstimer *) timer{NSLog (@"Timerfire begin"); NSLog (@"Timerfire End");}

So that we can achieve our own runloop.

Description: 1, do this simplerunloop just to let everyone more clear understanding of runloop principle, and will not put into actual use.

2, Simplerunloop in the Executeonce function must be _timerqueue copy to Enumarry, because in

It is not possible to modify the number of tuples in an array during traversal. This way, if you can continue to create a new timerfire in Viewcontroller

The Simpletimer event source is added to the queue. Or Viewcontroller Timerfire continues to invoke the

[Simplerunloop Rununtildate] Creates a sub-loop of Simplerunloop. At this point, if you add the Simpletimer event source to Simplerunloop,

An event-triggered call is called in this loop. Is the same as in the previous article Nsrunloop.

3, the Nsrunloop implementation of the system is certainly not so simple. So what's the difference between our simplerunloop and Nsrunloop, I think I have the following:
The input source for the input event source Simplerunloop can only be addtimer. While the system has port-based sources automatically sent by the kernel, Custom Input sources need to be sent manually from other threads. This is the key, if we can do these two actually can be a real nsrunloop. This can continue in-depth study.

Explore Runloop (ii) (Runloop self-fulfilling runloop)

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.