【iOS】ZXingのimageWithMatrixメソッドにてEXC_BAD_ACCESSが起きて落ちる


既存のアプリ(iOS - objective-c)をバージョンアップしたxcode(9→10)で出力しiOSアプリの動作確認をしていた所、画面遷移時に急にアプリが落ちる現象に見舞われたので、その時の行った修正対応を残しておきます。

発端

私のケースの場合、xcode10で出力したreleaseビルドにおいてのみ発生、ある特定の画面に遷移時、アラートも無くアプリが落ちる現象が起きた。端末によってまちまちだが、100%落ちるというわけでは無く十数回に1度くらいは遷移に成功した。遷移成功時の画面を確認した際に本来QRコードが表示されている部分が、なにも表示されていない状態だった為、バーコードを生成するライブラリZXing辺りの調査を行った。

解決策

・問題となったコード(一部)

UIImage *img;
ZXMultiFormatWriter* writer = [ZXMultiFormatWriter writer];
ZXBitMatrix* result;
NSError *error = nil;

result = [writer encode:fromString
         format:kBarcodeFormatQRCode
          width:hoge.width
          height:hoge.height
          error:&error];

if (result) {
    CGImageRef image = [[ZXImage imageWithMatrix:result] cgimage];
    img = [UIImage imageWithCGImage:image];
}

return img;

上記のコードの下部 if(result) で囲まれているコードの

CGImageRef image = [[ZXImage imageWithMatrix:result] cgimage];

でEXC_BAD_ACCESSが発生していた。

・コードを以下のように修正

● 修正前
(ZXImageインスタンスを生成し、imageWithMatrixを呼び出し、戻ってきた返り値のcgimageをそのまま変数に保持する)

CGImageRef image = [[ZXImage imageWithMatrix:result] cgimage];
img = [UIImage imageWithCGImage:image];

○ 修正後
(ZXImageインスタンスを生成し、imageWithMatrixの返り値を保持し、その保持した変数からcgimageを使う)

ZXImage *image = [ZXImage imageWithMatrix:result];
img = [UIImage imageWithCGImage:image.cgimage];

★参考
https://github.com/TheLevelUp/ZXingObjC/issues/146

さいごに

デバッグビルドでは、事象が起きなかったため、問題の特定含め、解決に時間がかかった為共有しておきます、処理タイミングがあってないとZXImageのインスタンスが消えちゃう的な事なのでしょうか?

xcode9以前のビルドではデバッグ、リリース共に正常に動いていたことも不思議です。

今回起こった事象はobjective-cのコード内で起きたことですが、もしかするとswiftでも起きるのかもしれませんので、cgimageを直接変数に入れず、ZXImageのインスタンスを残すように作った方がよいかもしれないです。
objective-c使いたくない