Как управлять памятью при использовании draw (в ctx: CGContext) в пользовательском CAShapeLayer? - PullRequest
0 голосов
/ 04 апреля 2019

Я создаю приложение для окраски SVG и у меня есть пользовательский слой CAShapeLayer для рисования радиальных градиентов.В моем приложении у меня обычно около 300 таких слоев для SVG.Мой код работает нормально.Но проблема в том, что мне очень быстро не хватает памяти при рисовании градиентов в CAShapeLayer с использованием метода draw(in ctx: CGContext).Я хочу очистить память, чтобы приложение не зависало.

Вот более простая версия моего пользовательского кода CAShapeLayer:

import Foundation
import QuartzCore
class MyCAShapeLayer: CAShapeLayer {
    public func updateLayer() {
        self.fillColor = nil
        self.setNeedsDisplay()
    }
    override func draw(in ctx: CGContext) {
        ctx.saveGState()
        if (self.path != nil) {
            ctx.addPath(self.path!)
            ctx.clip()
        }
        let numberOfLocations: Int = 2;
        let gradientLocations: [CGFloat] = [0.0, 1.0]
        let gradientComponents: [CGFloat] = [1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0];
        let colorSpace: CGColorSpace = CGColorSpaceCreateDeviceRGB()
        let gradient: CGGradient = CGGradient(colorSpace: colorSpace, colorComponents: gradientComponents, locations: gradientLocations, count: numberOfLocations)!
        let gradientCenter: CGPoint = CGPoint(x: self.bounds.size.width / 2, y: self.bounds.size.height / 2)
        let gradientRadius: CGFloat = min(self.bounds.size.width, self.bounds.size.height)
        ctx.drawRadialGradient(gradient, startCenter: gradientCenter, startRadius: 0, endCenter: gradientCenter, endRadius: gradientRadius / 2, options: .drawsAfterEndLocation)
        ctx.restoreGState()
    }
}

Вот мой ViewController.swift: Это неактуальный код.Но это то, что просто происходит под капотом при рендеринге SVG.Я создаю CAShapeLayer для каждого элемента SVG и добавляю его в подслой представления.Тем временем я сохраняю его в массиве для будущих операций.

for i in 0...35 {
    let layer: MyCAShapeLayer = MyCAShapeLayer()
    let rect: CGRect = CGRect(x: i * 10, y: i * 10, width: 700 - (i * 20), height: 700 - (i * 20))
    let path: CGPath = CGPath(rect: rect, transform: nil)
    layer.path = path
    layer.fillColor = UIColor.white.cgColor
    layer.strokeColor = UIColor.black.cgColor
    layer.bounds = path.boundingBoxOfPath
    layer.frame = layer.bounds
    self.view.layer.addSublayer(layer)
    self.shapeLayerList.append(layer)
}

И OnTap я рисую градиент на каждом слое.

self.shapeLayerList.forEach {
    shapeLayer in
    shapeLayer.updateLayer()
}

Здесь память будет быстро увеличиваться и при наличии около 300 слоев приложенияне хватит памяти.

Есть ли способ управления памятью при рисовании?Любое предложение будет оценено.

...