Swift5初心者です。ストーリーボードは使っておりません。
自作のペイントアプリで、ユーザーがペンで書き込んだ線の描画処理が重くなる、という問題を解決したいと考えています。
現在、描画のためのキャンバス上の処理は以下のようになっています。(一部抜粋)
ユーザーからtouch
系のイベントを受ける度にそのタッチされた座標(point
)を線lines
配列に追加し、
setNeedsDisplay
を呼ぶことでdraw
から線lines
を描画しています。
Swift
1Canvas: UIView { 2 3... 4 5 override func draw(_ rect: CGRect){ 6 super.draw(rect) 7 guard let context = UIGraphicsGetCurrentContext() else { return } 8 9 lines.forEach { (line) in 10 ... 11 for (i, p) in line.points.enumerated() { 12 if i == 0 { 13 context.move(to: p) 14 } else { 15 context.addLine(to: p) 16 } 17 } 18 context.strokePath() 19 } 20 } 21 22 override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { 23 if let touch = touches.first { 24 lines.append() 25 } 26 } 27 28 override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) { 29 if let touch = touches.first { 30 guard let point = touches.first?.location(in: nil) else { return } 31 let l: Line = lines.pop() 32 l.points.append(point) 33 lines.append(l) 34 setNeedsDisplay() 35 } 36 } 37 override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) { 38 if let touch = touches.first { 39 lines.store() 40 } 41 } 42 43}
また、描画された各線はtouchesEnded
内のlines.store()
でRealmデータベースにそれぞれ保存していきます。
この実装でキャンバスに線を100本、200本と描画していくと、最初は滑らかに描けていた線が、徐々に重く、カクカクとした線が描かれるようになっていきます。
例えば横に一本線を引いた時、前半部分は描けず後半部分だけキャンバスに描画される、というような挙動になります。
このアプリではキャンバスの複数枚の切り替えも行うことができ、新しいキャンバスに切り替えた場合はlines
を一度初期化(Realmには保存済み)しているのですが、重い動作は直りません(最初からカクカクとした線しか描けません)。
また、一度アプリ自体を落として再び起動すると、問題は解決され滑らかな線が描けるようになります。
(そのため、現在は描画が重くなってくるたびにアプリを再起動することで問題に対処しております。)
なぜこのような問題が現れるのでしょうか。
Realm保存時やlines
配列へのアクセス時にキャッシュのようなものがどんどん溜まっていっているのかなあと思っていますが、それ以上の考えが思い浮かびませんでした。
原因として考えられる処理、手がかり、解決策などを教えていただきたいです。
全く別の実装による機能実現のアイディアなどでも構いません。
よろしくお願いいたします。
回答1件
あなたの回答
tips
プレビュー