DWR3 Implementation Message Precise Push Detailed Step


UIMAGEVIEW has an AnimationImages property to play animation to imitate the attribute of UIImageView, and use CadisplayLink to play frame animation.

1. Introduction (original address: http://www.tuicool.com/articleS/memvr3))

1, the framework


CadisplayLink is the same as other Coreanimation classes, all in Quartzcore.framework.

2, function

CadisplayLink’s main feature is that it can provide a periodic call for the Selector that we give it to it. From this point of view, it is similar to the timer Nstimer.

3. How to use


- (void)startDisplayLink
    self.displayLink = [CADisplayLink displayLinkWithTarget:self
    [self.displayLink addToRunLoop:[NSRunLoop currentRunLoop]

- (void)handleDisplayLink:(CADisplayLink *)displayLink
  //do something

- (void)stopDisplayLink
    [self.displayLink invalidate];
    self.displayLink = nil;

When the CadisplayLink object adds it into Runloop, the selector can be called periodically, similar to the startup of Nstimer; when performing the Involution operation, the CadisplayLink object will be removed from the RunLoop. SELECTOR calls stop, similar to it, similar to Nstimer’s INVALIDATE method.

2, Features

The following combined with nstimer to introduce CadisplayLink. It is different from Nstimer:

1. Different principles

CadisplayLink is a timer class that allows us to draw a specific content on the screen at a frequency that allows us to synchronize with the screen refresh rate. After CADISPLAYLINK is registered with a specific mode to Runloop, when the screen display content is completed, Runloop will send a specified selector message to the target specified by CadisplayLink, and the selector corresponding to the CadisplayLink class will be called once.

Nstimer registered with Runloop in the specified mode. After the setting period is reached, Runloop sends a specified selector message to the specified target.

2, different cycle settings different ways

The screen refreshing frequency (FPS) of the

iOS device is 60Hz, so CadisplayLink’s selector’s default call cycle is 60 times per second. This cycle can be set through the frameinterval attribute. For example, when Frameinterval is set to 2, calls are called 30 times per second. Therefore, the setting of the CadisplayLink cycle is slightly inconvenient.

nstimer’s selector call cycle can be set directly when initialization, which is relatively flexible.

3. Different accuracy

The screen refreshing frequency of

iOS device is fixed. CadisplayLink will be called at each refresh, and the accuracy is quite high.

The accuracy of the

Nstimer is a bit lower. For example, when the trigger time of Nstimer is over, if the Runloop is busy with other calls, the trigger time will be postponed to the next Runloop cycle. What’s more, after OS X V10.9, in order to avoid triggering the time to the NSTimer to interrupt the current processing task, Nstimer adds the TOLARANCE attribute, allowing users to set the time range that can tolerate triggers.

4. Use occasions

In principle, it is not difficult to see that the use of CadisplayLink is relatively dedicated, suitable for constant re -painting for interfaces. For example, when video playback, you need to constantly obtain the next frame for interface rendering.

Nstimer’s use range is much widespread, and all kinds of tasks that require single or loop regular processing can be used.

3, important attributes

The incompletely listed several important attributes of CadisplayLink:

1、 frameInterval

Reading and write -able NSINTEGER type value, the identifier interval how many frames are called once the selector method, the default value is 1, that is, call once every frame. The official document emphasizes that when the value is set less than 1, the result is unpredictable.


Read the CFTIMEINTERVAL value, indicating the time interval between the two screen refresh. It should be noted that this attribute will be assigned only after being called for the first time. SELECTOR call interval time calculation method is: time = duration × frameintervalval.

The FPS of the existing iOS device screen is 60Hz, which can be seen from the Duration property of CadisplayLink. The values of Duration are 0.1666666, that is, 1/60. Nevertheless, we can’t sure that Apple will not change the FPS. What if the FPS will be raised to 120Hz one day in the future? At this time, you set up the FrameInterval attribute value of 2 and expect to refresh 30 times per second, but find that it has been refreshed 60 times per second. As a result, you can imagine that, out of security considerations, first judge the screen of the screen based on the Duration. Essence


The CFTIMEINTERVAL value that only reads, indicates the timestamp of the previous frame display of the screen. This attribute is usually used by target to calculate the content that should be displayed in the next frame.
Print the TimestAmp value, its style is similar to:

Although the

is called the timestamp, it is very different from the common UNIX timestamp. In fact, this is the time format used by Coreanimation. Each calay has a local time (the specific role of Calayer’s local time will be explained in the subsequent article), which can get the current Calay’s local time and print:

CFTimeInterval localLayerTime = [myLayer convertTime:CACurrentMediaTime() fromLayer:nil];

Four, pay attention

iOS does not guarantee that the callback method can be called 60 times per second, which depends on:

1. The degree of leisure of CPU

If the CPU is busy with other calculations, it will not guarantee that the 60Hz execution of the screen drawing action will cause the opportunity to skip several callback methods, and the number of times is determined to be the busyness of the CPU.

2. The time used to execute the callback method

If the delation time is greater than the interval between the redemption, it will cause a number of chance of callback calls, depending on the length of the execution time.

Below use CadisplayLink to play frame animation
1. RewritingUIImageView 


//  AnimationImageView.h

//  UseCADisplayLinkPlay animation


//  Created by dengyanzhou on 15/1/30.

//  Copyright (c) 2015year mobby. All rights reserved.


#import <UIKit/UIKit.h>

typedef  void (^AnimationComplete) (BOOL isFinished);

@interface AnimationImageView : UIImageView

@property(nonatomic)int  step;

@property(nonatomic,strong)NSArray *animationImageArray;//The picture frame number array to be played

@property(nonatomic,copy)AnimationComplete tempAnimationComplete;

@property(nonatomic,assign)int  index; //Positioning the picture currently played

@property(nonatomic)float  animationTime; // Animation duration

@property(nonatomic)int   count;

@property(nonatomic )float   frequency; // frequency

@property(nonatomicint transformatRate; //conversion rate

@property(nonatomic,strong)CADisplayLink*Displaylink; // timer

– (void)playAnimationWithImageArray:(NSArray*)animationArray durationTime:(float)time complete:(AnimationComplete)animationComplete;


// Implementation file


//  AnimationImageView.m

//  UseCADisplayLinkPlay animation


//  Created by dengyanzhou on 15/1/30.

//  Copyright (c) 2015year mobby. All rights reserved.


#import “AnimationImageView.h”

#import “UIImageAdditions.h”

@implementation AnimationImageView

– (void)playAnimationWithImageArray:(NSArray*)animationArray durationTime:(float)time complete:(AnimationComplete)animationComplete{

    // Animation playback array is empty Return directly  The animation is not completed;

        if (!animationArray.count  ) {




    //Time is zero Return directly

    if (time <= 0) {



    self.frequency = time/animationArray.count;

    self.transformatRate = (int)(self.frequency * 60);

    if (self.transformatRate == 0) {

        self.transformatRate = 1;


    //_disPlayelink There are still indicating that the animation is not completed

    if (self.displayLink) {

        //Make the animation stop

        [_displayLink invalidate];

        _displayLink = nil;

        //count Return again 0

        _count = 0;

        _index = 0;




    self.animationImageArray = animationArray;

    self.animationTime = time;

    _count = 0;

    _index = 0;

        // timer

    self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateImage:)];

    [self.displayLink addToRunLoop:[NSRunLoop mainRunLoop]forMode:NSDefaultRunLoopMode];

       _tempAnimationComplete = animationComplete;


– (void)updateImage:(CADisplayLink*)displayLink{


    if (++_count % self.transformatRate == 0 ) {

        self.image = [UIImage getPNGImage: [_animationImageArray objectAtIndex:_index]];

        //Animation complete

        if (_index == self.animationImageArray.count1) {

            [_displayLink invalidate];

            _displayLink = nil;

            self.animationImageArray = nil;

            // Animation is completed block







// In case of institutionalization in viewControAnimationImageView and call

AnimationImageView object

– (void)playAnimationWithImageArray:(NSArray*)animationArray durationTime:(float)time complete:(AnimationComplete) AnimationComplete method


//  ViewController.h

//  UseCADisplayLinkPlay animation


//  Created by dengyanzhou on 15/1/30.

//  Copyright (c) 2015year mobby. All rights reserved.


#import <UIKit/UIKit.h>

@interface ViewController : UIViewController



//  ViewController.m

//  UseCADisplayLinkPlay animation


//  Created by dengyanzhou on 15/1/30.

//  Copyright (c) 2015year mobby. All rights reserved.


#import “ViewController.h”

#import “AnimationImageView.h”

@interface ViewController (){

    NSMutableArray *imageArray;

    AnimationImageView *imageView;



@implementation ViewController

– (void)viewDidLoad {

    [super viewDidLoad];

    self.view.backgroundColor = [UIColor grayColor];

     imageView = [[AnimationImageView alloc]initWithFrame:CGRectMake(100, 200, 320, 300)];

    [self.view addSubview:imageView];

    imageView.backgroundColor = [UIColor redColor];

    imageArray = [NSMutableArray array];

    for (int i = 1;  i <= 68; i++) {

//        NSString *imageName = @”7-8_Game2_bulusi 300″;

      NSString  *imageName = [NSString stringWithFormat:@”7-8_Game2_bulusi 300%02d”,i];

      // UIImage   *image = [UIImage imageNamed:imageName];

        [imageArray addObject:imageName];


    UIButton  *button = [UIButton buttonWithType:UIButtonTypeCustom];

    button.frameCGRectMake(700, 400, 200, 80);

    button.backgroundColor = [UIColor blueColor];

    [button setTitle:@”Click to play forState:UIControlStateNormal];

    [button addTarget:self action:@selector(buttonClick) forControlEvents:UIControlEventTouchUpInside];

    [self.view addSubview:button];

#if !__has_feature(objc_arc)  // If notarc

    [imageArray relese];


    // Do any additional setup after loading the view, typically from a nib.


– (void)buttonClick{

//    imageView.animationImages =  [NSArray arrayWithArray:imageArray];

//    imageView.animationRepeatCount = 1;

//    imageView.animationDuration = 4.0f;

//    [imageView startAnimating] ;

[imageView playAnimationWithImageArray imageArray durationTime:3 complete:^(BOOL isFinished) {

    if (isFinished) {

        NSLog(@”Animation complete);


      NSLog(@”The animation is not completed);




– (void)didReceiveMemoryWarning {

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.




Related Posts

ListView uses the getView problem NEO

SpringBoot entry (1)

jsp: usebean, jsp: setproperty Detailed explanation

Talk about Vue component welkin

DWR3 Implementation Message Precise Push Detailed Step

Random Posts

kurento to build video server and DEMO demonstration


WeChat Mini Program Introduction to Weui component library (detailed successful case, with diagram)

SDUT minimum intercept system Guojing

About Form Form acquisition value and setting worthy method