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

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

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

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

メモリリーク

メモリリークは、プログラムファイルがメモリの解放に失敗した時に起こります。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

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

Q&A

1回答

3964閲覧

Swift 端末内に入っている写真を取得する際アプリが落ちてしまう。

kizahashi

総合スコア17

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

メモリリーク

メモリリークは、プログラムファイルがメモリの解放に失敗した時に起こります。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

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

0グッド

1クリップ

投稿2018/07/16 11:23

SwiftにてcollectionView をつかったアルバムアプリを作成しております。

PHAsset.fetchAssetにてPHAssetを取得し
PHCachingImageManagerにて画像を表示しています。

画像のサイズが200×200ですとギリギリ表示されるのですが
画像のサイズを400×400などに設定するとほぼ動作しなくなり

Swift

1Message from debugger: Terminated due to memory issue 2 3[GatekeeperXPC] Connection to assetsd was interrupted or assetsd died

などのメッセージが出てアプリが落ちてしまいます。

今の所以下のようなやり方でスマートアルバム、アルバムを取得しています。

Swift

1func getPhotos(albumName1: PHAssetCollectionType, albumName2: PHAssetCollectionSubtype){ 2// let imgManager = PHImageManager.default() 3 let cacheManeger = PHCachingImageManager() 4 cacheManeger.allowsCachingHighQualityImages = false 5 6 let requestOptions = PHImageRequestOptions() 7 requestOptions.isSynchronous = false 8 requestOptions.deliveryMode = .highQualityFormat 9 10 let fetchOptions = PHFetchOptions() 11 fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)] 12 13 14// アセットコレクションを取得 15 let assetCollections = PHAssetCollection.fetchAssetCollections(with: albumName1, subtype: albumName2, options: nil) 16 17 assetCollections.enumerateObjects { assetCollection, index, stop in 18 19 // アセットを取得 20 let assets = PHAsset.fetchAssets(in: assetCollection, options: fetchOptions) 21 22 23 24 assets.enumerateObjects { asset, index, stop in 25 26 cacheManeger.startCachingImages(for: [asset], targetSize: CGSize(width: 200, height: 200), contentMode: .aspectFill, options: requestOptions) 27 28 cacheManeger.requestImage(for: asset, targetSize: CGSize(width: 200, height: 200), contentMode: .aspectFill, options: requestOptions, resultHandler: { img, _ in 29// DispatchQueue.global().async { 30 31 if let img2 = img { 32 // print("画像の取得に成功") 33 34 if assetCollection.localizedTitle == "(selectAlbum)" 35 { 36 imageArray.append(img2) 37 }else if assetCollection.assetCollectionType == .smartAlbum{ 38 imageArray.append(img2) 39 40 } 41 photosTotalAmount = [Int](0...imageArray.count) 42 43 } 44 }) 45 46 } 47 } 48 }

app storeで配信されているアルバムアプリやカメラアプリの写真選択画面などでは、ほぼ全ての画像が高画質で3秒も経たぬうちに読み込まれて表示されています。

なぜそんなに高速なのでしょうかPHImageManager以外の方法、ライブラリなどあるのでしょうか?
いまのやり方ですと写真5000枚程度のカメラロールを取得するのに早くても5秒。遅くて10秒を超えてしまいます。

そのほかにやったこととしては
サブスレッドで画像を取得。
collectionView.reloadDataを一定の枚数取得したら実行。
など試しましたがやはり基本の読み込みスピードからして遅い気がします。

まとめますと、アプリが落ちないように、また写真取得を高速化するにはどこを改善すれば良いでしょうか?

解決法、ヒント等いただけたら幸いです。
よろしくお願いいたします。

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

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

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

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

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

guest

回答1

0

要件にもよりますが、まずは5000枚端末に入っていても表示するだけが要件であれば、画面に表示出来る枚数+αだけ読み込んだら良いと思います。
5000枚を読み込んだ後に表示をするというロジックであれば、限界が来ることは必然です。
またアプリが落ちる原因として考えるられるのもメモリ不足です。
こちらも同じ理由で画面に表示出来る枚数に限定してロードすることでメモリは足りると思います。
参考になれば、幸いです。

投稿2018/07/17 00:34

YasuhiroMiyake

総合スコア1336

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問