2017-04-25 159 views
0

我用戶一個計時器射擊每0.1秒的功能重複使用UIGraphicsGetImageFromCurrentImageContext得到一個UIImage並分配到一個@IBOutllet弱UImageView.image。(coverImageView)的iOS內存警告

var timer:Timer? 

func fireTimer() { 
    timer = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true, block: { [weak self] _ in 
     self?.lightTheFier() 
    }) 
} 

func invalidateTimer() { 
    timer?.invalidate() 
    timer = nil 
} 

func lightTheFier() { 
    var points = [CGPoint]() 
    for pin in pins { 
     let point = mapView.convert(pin.coordinate, toPointTo: coverImageView) 
     points.append(point) 
    } 
    coverImageView.image = getMaskedImage(points: points, zoomLevel: Int(mapView.zoomLevel())) 
} 

func getOringinalImageFromPath() -> UIImage{ 
    UIGraphicsBeginImageContextWithOptions(coverImageView.bounds.size, false, 0.0) 
    let path = UIBezierPath(rect: coverImageView.bounds) 
    UIColor.black.setFill() 
    path.fill() 
    let image = UIGraphicsGetImageFromCurrentImageContext() 
    UIGraphicsEndImageContext() 
    return image! 
} 

func getMaskImageFromPath(points:[CGPoint], scale:CGFloat) -> UIImage { 
    UIGraphicsBeginImageContextWithOptions(coverImageView.bounds.size, false, 0.0) 
    let radius:CGFloat = 10.0 
    UIColor.blue.setFill() 
    for point in points { 
     let rect = CGRect(x: point.x - (scale*radius/2), y: point.y - (scale*radius/2), width: scale*radius, height: scale*radius) 
     let path = UIBezierPath(ovalIn: rect) 
     path.fill() 
    } 
    let image = UIGraphicsGetImageFromCurrentImageContext() 
    UIGraphicsEndImageContext() 
    return image! 
} 

func getMaskedImage(points:[CGPoint], zoomLevel:Int) -> UIImage{ 
    let orImage = getOringinalImageFromPath().cgImage 
    let maskImage = getMaskImageFromPath(points: points, scale: CGFloat(zoomLevel)).cgImage 
    let mask = CGImage(maskWidth: maskImage!.width, height: maskImage!.height, bitsPerComponent: maskImage!.bitsPerComponent, bitsPerPixel: maskImage!.bitsPerPixel, bytesPerRow: maskImage!.bytesPerRow, provider: maskImage!.dataProvider!, decode: nil, shouldInterpolate: true) 
    let maskRef = orImage?.masking(mask!) 
    let image = UIImage(cgImage: maskRef!) 
    return image 
} 

所有代碼以上是在ViewController.swift中進行測試。

在函數運行過程中,內存越來越大,我想要的是當我使計時器無效時,它可以釋放內存。

我該如何解決這個問題?

+1

放,你必須嘗試 –

+0

我已編輯它的代碼,謝謝! –

+0

在ARC中,某些變量被釋放,所有使用該變量的變量都需要超出範圍。看看'coverImageView'將會超出範圍。更好的方法是在需要時請求圖像,而不是使用定時器。因此,當圖像需要顯示時,檢查圖像是否已經可用,否則獲取它。 – user1046037

回答

0

你開始一個圖像上下文:UIGraphicsBeginImageContextWithOptions,但你永遠不會結束它。您需要添加UIGraphicsEndImageContext()getMaskImageFromPathgetOringinalImageFromPath方法:

func getMaskImageFromPath(points:[CGPoint], scale:CGFloat) -> UIImage { 
    UIGraphicsBeginImageContextWithOptions(coverImageView.bounds.size, false, 0.0) 
    let radius:CGFloat = 10.0 
    UIColor.blue.setFill() 
    for point in points { 
     let rect = CGRect(x: point.x - (scale*radius/2), y: point.y - (scale*radius/2), width: scale*radius, height: scale*radius) 
     let path = UIBezierPath(ovalIn: rect) 
     path.fill() 
    } 
    let image = UIGraphicsGetImageFromCurrentImageContext() 
    UIGraphicsEndImageContext() // Missing this line 
    return image! 
} 
+0

運行循環保留定時器。 –

+0

嗨,戴夫,我修好並運行後,它節省了大量的內存!那麼,但記憶只會增加,但在我繼續開火併使計時器失效後永不減少,我該如何解決它呢? –

+0

或者,也許給我指示,找出問題所在,非常感謝! –