         }
         
         let frameProperties = imageProperties.map(){
-                unsafeBitCast(
-                    CFDictionaryGetValue($0,
-                        unsafeAddressOf(kCGImagePropertyGIFDictionary)),                CFDictionary.self)
+            unsafeBitCast(
+                CFDictionaryGetValue($0,
+                    unsafeAddressOf(kCGImagePropertyGIFDictionary)),                CFDictionary.self)
         }
         
         let frameDelays:[Float] = frameProperties.map(){
             var delayObject: AnyObject = unsafeBitCast(
-                    CFDictionaryGetValue($0,
-                        unsafeAddressOf(kCGImagePropertyGIFUnclampedDelayTime)),
-                    AnyObject.self)
+                CFDictionaryGetValue($0,
+                    unsafeAddressOf(kCGImagePropertyGIFUnclampedDelayTime)),
+                AnyObject.self)
+            
             let EPS = 10e-10
             if(delayObject.doubleValue<EPS){
                 delayObject = unsafeBitCast(CFDictionaryGetValue($0,
-                        unsafeAddressOf(kCGImagePropertyGIFDelayTime)), AnyObject.self)
+                    unsafeAddressOf(kCGImagePropertyGIFDelayTime)), AnyObject.self)
             }
             return delayObject as! Float
         }
         return frameDelays
     }
     
-    typealias FrameDelays = [Float]
-    private func CalculateFrameDelay(var delays:FrameDelays)
+    private func CalculateFrameDelay(var delays:[Float])
     {
         
         //Factors send to CADisplayLink.frameInterval

    //bound to 'displayLink'
    func updateFrame(){
        image = self.currentImage
        //self.layer.setNeedsDisplay()
        dispatch_async(queue,setCurrentImage)
    }
    
    let queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH,0)
    
    

    func setCurrentImage()
    {
        if(self.frameCache.count == 0){frameProducter()}
        frameConsumer()
    }
    
    
    //product UIImage into frameCache
    private func frameProducter(){
            for _ in 0..<self.frameCacheMaxNumber{
            let cgImage = CGImageSourceCreateImageAtIndex(self.imageSource!,self.displayOrder[self.displayOrderIndex],nil)!
            self.frameCache.append(UIImage(CGImage:cgImage))
            self.displayOrderIndex = (self.displayOrderIndex+1)%self.imageCount
            }
    }


    //get the first image from frameCache,and remove it
    private func frameConsumer(){
        self.currentImage = self.frameCache.first
        self.frameCache.removeFirst()
    }
    
    
    private func GetDelayTimes()->[Float]{
        

public class JWAnimatedImageView:UIImageView
{
    
    //bound to function 'updateFrame'
    private lazy var displayLink: CADisplayLink = CADisplayLink(target: self, selector: Selector("updateFrame"))
    //has connecttion with CADisplayLink.frameInterval
    private var displayRefreshFactors = 1       //default
    
    //obtained from NSData
    private var imageSource: CGImageSourceRef?
    
    //indexs of frames choosed from imageSource and total number
    private var displayOrder = [Int]()
    private var imageCount = 0                  //initial
    
    //the level of integrity of a gif image,The range is 0%(0)~100%(1).we know that CADisplayLink.frameInterval affact the display frames per second,if it is larger, we will only dispaly fewer frames per second,in the other way,we will never display some of frames all the time.So,the level of integrity gives us a limit that the device should show how many frames at list.If it is 100%(1),that means the device displays frames as much as it can.The default number is 0.8,but you can decrease it for a less cpu usage.
    public var levelOfIntegrity:Float = 0.8    //default
    
    //add gif as NSData
    public func addGifImage(data:NSData){
        self.imageSource = CGImageSourceCreateWithData(data, nil)
        
        //set cover
        self.currentImage = UIImage(CGImage: CGImageSourceCreateImageAtIndex(self.imageSource!,0,nil)!)
        
        CalculateFrameDelay(GetDelayTimes())
        
        self.displayLink.frameInterval = self.displayRefreshFactors
        self.displayLink.addToRunLoop(.mainRunLoop(), forMode: NSRunLoopCommonModes)
    }
    
    //image that will be displayed next
    public var currentImage:UIImage?
    
    //the current index of frames when display the gif
    private var displayOrderIndex = 0
    
    //dispatch queue
    private let queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH,0)
    
    //this is an empty function,but program won't work if I delete it,and I don't know why
    override public func displayLayer(layer: CALayer){}
