質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
SpriteKit

SpriteKitは、iOSやOS Xで使用できるApple社製の2Dゲーム開発フレームワークです。

Cocoa

CocoaはMac OS X用のアプリケーションを構築する為の主要なフレームワークのひとつです。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Swift 2

Swift 2は、Apple社が独自に開発を行っている言語「Swift」のアップグレード版です。iOSやOS X、さらにLinuxにも対応可能です。また、throws-catchベースのエラーハンドリングが追加されています。

Q&A

1回答

2444閲覧

NSImageViewのNSImage切り替え時にメモリが解放されていない?

退会済みユーザー

退会済みユーザー

総合スコア0

SpriteKit

SpriteKitは、iOSやOS Xで使用できるApple社製の2Dゲーム開発フレームワークです。

Cocoa

CocoaはMac OS X用のアプリケーションを構築する為の主要なフレームワークのひとつです。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Swift 2

Swift 2は、Apple社が独自に開発を行っている言語「Swift」のアップグレード版です。iOSやOS X、さらにLinuxにも対応可能です。また、throws-catchベースのエラーハンドリングが追加されています。

0グッド

0クリップ

投稿2016/07/15 21:40

###前提・実現したいこと
macOSアプリ開発です。NSImageViewクラスのimageプロパティに入れるNSImageインスタンスを素早く切り替えることで、アニメーションのようなものを実装しようとしています。見た目は正常にアニメーションできるのですが、アニメーション時にメモリを激しく消費します。メモリの消費を抑えてアニメーション処理したいです。

###発生している問題・エラーメッセージ
イメージ説明

###該当のソースコード
SpriteKitと併用しています。省略していますが構造は同じです。

Swift

1class GameScene: SKScene { 2 let imageView = NSImageView(frame: NSRect(x: 0, y: 0, width: 300, height: 300)) 3 let imageArray = [NSImage?](count: 1000, repeatedValue: nil) 4 5 override func didMoveToView(view: SKView) { 6 view.addSubview(imageView) 7 for i in 0..<1000 { 8 let image = NSImage(contentsOfFile: filePath) // 任意のパス 9 imageArray[i] 10 } 11 } 12 13 override func update(currentTime: CFTimeInterval) { 14 ・・・ 15 imageView.image = imageArray[index] // 任意のindex 16 } 17}

###試したこと
0. Instruments>Leaksでアプリ追跡
→NSImageやNSImageViewに関するメモリリークはなかった
0. imageView.image = imageArray[index]の後にimageView.image = nilを追加
→メモリは消費されないが画像も表示されない
0. imageView.image = imageArray[index]の直前にimageView.image = nilを追加
→追加しない時と同じ挙動
0. update()の最初にimageView.image = nilを追加
(いくつかの処理をしたのちimageView.image = imageArray[index]が実行される)
→点滅したようなアニメーションになる。メモリの消費は追加しない時と同じ
0. imageView.imageに同一インスタンスを代入し続けてみる
→メモリが数MB使われるがそれ以上は増加しない
0. 切り替える画像の数を変えてみる
→切り替える画像の種類が多いほどメモリが使われている...ように思える
0. 同じ画像から複数のNSImageインスタンスを生成し、imageView.imageに順番に入れる
→メモリが数MB使われるがそれ以上は増加しない(5.と同じ?)
0. 画像を読み込む処理をautoreleasepool{}ではさむ
→変化なし
0. view.addSubview(imageView)をはずす
→メモリは消費されないが画像も表示されない

おそらく「新しい画像データをレンダリングするとメモリを消費する」のだと思いますが推測の域を出ません。そうだとしても解決策が思い浮かばずお手上げ状態です。

###補足情報(言語/FW/ツール等のバージョンなど)
Swift 2.2
Xcode 7.3.1
OSX 10.11.5

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

提示されたコードを見ましたが、
imageArray[i]

imageArray[i] = image

let imageArray = [NSImage?](count: 1000, repeatedValue: nil)

var imageArray = [NSImage?](count: 1000, repeatedValue: nil)
を修正しないとビルドでエラーになると思います。
それを修正すれば、このコード自体は問題なさそうに思います。

ただ、気になるのはdidMoveToViewが何度も呼ばれるような状況になっていないかです。
このGameSceneを表示するのに何度もpresentSceneしたりしていませんか?
もしそれをやっているなら、didMoveToViewが何度も呼ばれ、NSImageViewをaddSubviewでどんどん積み重ねていくことになると思います。
didMoveToViewのところでブレークポイントを設定するかログを出力するかして、何度も呼ばれる状況になっていないか確認してみることをお勧めします。

投稿2016/07/18 07:14

TakeOne

総合スコア6299

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問