杏z学習帳

Swift、Unityなどを中心に節操なく手を出してますまる

Share Extension…もしかしてメモリリークしてるかもっていう話(2019/02/18)

[Swift]Share Extension…もしかしてメモリリークしてるかもっていう話

ざっくりまとめ。

です。

環境

問題

公開しているアプリツイクラでツイートを繰り返し登録していると
登録画面を表示した段階ですぐさま消える(多分クラッシュしている)という問題が発生していました。

こういう動作を繰り返し行っているとそのうち、登録画面を表示しただけですぐに消えるっていう感じですね。
このツイート登録画面は Share Extension で実装しています。
いちどその問題が発生したあとはしばらくはまた大丈夫になります。

調査

コードを見直しても怪しいところが見つからなかったので、とりあえず最小コードのものを作ってから、
そこから少しずつ肉付けていってアタリをつけようかとおもって、
新規プロジェクトをつくって Share Extension を追加しただけのものを作って、
上記 Gif と同じ様に繰り返し操作してみると...

同じ様に落ちました

ちなみに、その時のコードは下記の通り

class ShareViewController: SLComposeServiceViewController {

    override func isContentValid() -> Bool {
        return true
    }

    override func didSelectPost() {
        self.extensionContext!.completeRequest(returningItems: [], completionHandler: nil)
    }

    override func configurationItems() -> [Any]! {
        return []
    }
}

ほんとになにもない(笑)

も少し詳しく

落ち方が有無を言わさずな感じというのと、1度発生するとまたしばらくは大丈夫ということから、メモリ周りが気になりみてみました。

Memory leaks

ちょっと分かりづらいですけど右肩上がり。。!😇
(スタートの方は40MBぐらい)
そして、コンソールの方には。。。

Got memory pressure notification

が吐かれていて、登録画面を開くたびにそれがどんどん吐かれる...。
クラッシュ寸前には、1回開いただけで3-4行ぐらい同じ warning 文がずらずらっと!
そして落ちたときには、

EXC_RESOURCE RESOURCE_TYPE_MEMORY(limit=XXX,unused=0x0)

というものが。。リーク。。。してますね!?🤔
試しに他のアプリで同じく Share Extension を使って作られているであろう共有画面を同じような操作(Twitter アプリからツイートの共有)してみたら、
そちらも同じく落ちましたね。。。

解決策(回避策といったほうがいいでしょうか)

リークしてるであろうということがわかったとは言え、、
コード見せたように何もしていない標準のママですしどうしようもないのか?とか思いたくもなりますが、
先程他のアプリでも同じくく落ちたとかきましたが、実は落ちなかったものもあるのです。

みんな大好き Slack

ということで、Slack とツイクラで何が違うのか見比べてみました。一目瞭然でした(笑)

プレビューがない!!

上記のGifだと最初 Safari っぽいロゴが表示されてちょっとして Twitter ロゴが表示されているところです。
画像を受け付けている場合は、そこに画像が表示されるはず。。のところ。
Slack のシェア画面にはそれがないのです。

ってことでやってみる

プレビュー機能消せるのですか?
消せます!上記コードに以下を追記します

override func loadPreviewView() -> UIView! {
    return UIView()
}

画像を受け付けている場合とかは無いとこまるでしょうが、ツイクラの場合正直いらない(消せるとは思っていなかった(笑))ので、サクッと消してみました。
結果、落ちなくなりました!!!!🎉

ということで、Share Extension つかってて同じ様な感じで落ちるな〜。でもたまにだし、まいっかとか思っていた方はここらみてみると良いかもです👍

補足

ただしこの問題、共有機能を有しているすべてのアプリで発生するわけではないです。。
たとえば Safari でページの共有を繰り返しやっても問題ないですし、
グノシーとかでも大丈夫でした。(もしかすると共有するページのURL次第では発生するかもですが)

僕が再現できたのは、

です。この2つのアプリでプレビューがある共有画面を繰り返し呼び出しているとそのうち落ちました。。
渡されるURL(該当サービスのWebサーバ側?)の問題というか相性というか、、そういう話なのでしょうか
なんにせよリークしちゃだめっていう話でもありますが。。
(使用できるメモリが少ない端末ほど発生するまでの繰り返し回数は少ないとは思います)
僕の端末依存なのでは!?疑惑も少なからずありますが、
同じ内容の問い合わせがツイクラに寄せられていたので少なくとも僕だけではないはずです(笑)
(その問い合わせもあってちょっと本格的に調査しだしたという...)