[2021.3.3更新/解決] NSURLSessionのメモリの扱いについてメモ

iOS 14で再確認すると修正済み

この記事の初版を投稿した頃の最新OSはiOS 8.1でした。当時は、この記事の後半に残してあるような問題がありました。しかし、iOS 14で再確認してみると問題は修正されていました。

テストアプリを作成し、約12GBのファイルをHTTPでダウンロードさせてみました。iOS 8.1の頃のような問題は再現せず、メモリの上昇も見られませんでした。iPhone Xsで試してみると、41MB付近で微増という感じでした。

NSURLConnectionやCFNetworkを使ったダウンロード処理に使用するAPIは既に非推奨APIになっています。そのため、NSURLSession (SwiftではURLSession) に移行する必要があります。

確認に使用したテストコードはGitHubの以下のリポジトリに置いておきます。

[GitHub] akirark/DownloadTest

iOS 8.1の頃の話

NSURLSessionですが、ダウンロードしたデータをオンメモリ(NSData)で渡してくれるメソッドとテンポラリファイルに書き込んで渡してくれるメソッドの両方がいます。普通に考えれば、テンポラリファイルの方は、ファイルに書きながらなので、巨大なファイルも扱えると思うのですが、iOS 8.1で見ていると、どうも中間のデータをオンメモリで持っていて、最後に書いている様子。そのため、途中でメモリ不足になって落ちてしまいます。
通信の後に、invalidateAndCancelで解放してあげないと、リークになることは明記されていますが、途中のデータの扱いがオンメモリで持っているかについては書かれていません。しかし、Instrumentsで見てみると、CFNetworkを内部で使っていて、データ受信用のコールバック関数の中で確保しているデータがダウンロード中は解放されていないことが確認できます。
これでは、巨大なファイルを落とす可能性があるアプリでは使えないですね。。。
巨大なファイルを落とす可能性があるアプリではNSURLConnectionやCFNetworkのAPIを使ってダウンロード処理を書いた方が良いようです。

投稿者プロフィール

林 晃
林 晃アプリ開発者
アールケー開発代表。Appleプラットフォーム向けのアプリ開発が好きなアプリ開発者。アプリの受託開発、技術書執筆、技術指導・セミナー講師。3DCGコンテンツ作成にも取組中です。

基礎から学ぶARKit


「基礎から学ぶARKit」を執筆しました。本書はARKitを使ったARアプリの開発方法を解説した技術書です。

ARKitを使ってARアプリを作るときの流れや基本的なAPIの使い方などをサンプルアプリを作りながら学べます。

詳細

基礎から学ぶMetal


「基礎から学ぶMetal」を執筆しました。本書はMetalを使ってGPUプログラミングを行うための最初のステップを解説するMetalの解説書です。

私が初めてGPUプログラミングを行ったとき、どこから手をつけて、学んでいけば良いのか分からず呆然としました。もし、あのとき、これを教えてくれればという部分を解説しました。本書で解説している部分はMetalの基礎となる部分で、Metalを使うときに必ず触れることになる部分です。

詳細

関連記事

  1. Xcodeの外部エディタを設定して効率アップ

  2. Qiitaにも投稿しています

  3. Lionを入れるには非力すぎた

  4. Xcodeのコーディング効率が上がるかもしれないTips

  5. AtomはUndo情報も覚えている

  6. HistoryEditor Windows版 1.5.1を公開しました…

最近の著書

  1. 基礎から学ぶ SwiftUI

最近の記事