原因不明でアプリがクラッシュすることが何度かあり、どうやら、アプリ内課金の関係で、Appleのサーバに問い合わせに行っている最中に、「遅い!もういいよ!」みたいな感じで画面遷移(具体的には、ナビゲーションの「戻る」を押す)をしてしまうと、ごく稀にこの問題が発生する、ということまで絞り込むことができた。
ごく稀にというのが、まあ、厄介なところ。
ちなみに、アプリがクラッシュした時のXcode(ちなみにバージョンは6.1)の表示はこんな感じ。
コードがこれ↓
スタックがこれ↓
これだけだと、さっぱり、意味がわからない。
"Enqueued from com.apple.root.default-qos"と"EXC_BAD_ACCESS"とかでググっても、なかなかこれというのが見つからないし、なんと言っても、"Enqueued from com.apple.root.default-qos"と"SKProductsRequest"の組み合わせで検索結果がゼロというのに参った。
SKProductsRequestのstartメソッド呼ばない限りクラッシュしないので、この関係だってことは間違い無いと思うんだけど…。
そして、結局、自分で、何が原因なのかわかりました。ので、情報共有です。
こんなコードを書いていたんですよ。どこかで見たコードのコピペですけど。
というわけで、僕が採った解決法はこれ。
まず、ヘッダファイルでこんな宣言。
これに加えて、viewWillDisappearで、delegateを無効化してやる処理を加えました。
そしたら、(今のところ?)ばっちり、っぽいです。なんか自信なさげな書き方で恐縮ですが。いかんせん、稀にしか起こらない問題なので断言が難しいのです。
コードがこれ↓
スタックがこれ↓
これだけだと、さっぱり、意味がわからない。
"Enqueued from com.apple.root.default-qos"と"EXC_BAD_ACCESS"とかでググっても、なかなかこれというのが見つからないし、なんと言っても、"Enqueued from com.apple.root.default-qos"と"SKProductsRequest"の組み合わせで検索結果がゼロというのに参った。
SKProductsRequestのstartメソッド呼ばない限りクラッシュしないので、この関係だってことは間違い無いと思うんだけど…。
そして、結局、自分で、何が原因なのかわかりました。ので、情報共有です。
こんなコードを書いていたんですよ。どこかで見たコードのコピペですけど。
これだと、サーバからのレスポンスを受け取った時に、selfがdeallocateされてしまった後だと、まずいことになるんですよね。productRequestの後始末が考慮されていない。- (void)startRequest { SKProductsRequest* productRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:[NSSet setWithArray:productIdentifiers]]; productRequest.delegate = self; [productRequest start]; }
というわけで、僕が採った解決法はこれ。
まず、ヘッダファイルでこんな宣言。
そして、本体コードでは、@property (nonatomic, strong) SKProductsRequest *productRequest;
- (void)startRequest { _productRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:[NSSet setWithArray:productIdentifiers]]; _productRequest.delegate = self; [_productRequest start]; }
これに加えて、viewWillDisappearで、delegateを無効化してやる処理を加えました。
- (void)viewWillDisappear:(BOOL)animated
{
_productRequest.delegate = nil;
[[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
}
そしたら、(今のところ?)ばっちり、っぽいです。なんか自信なさげな書き方で恐縮ですが。いかんせん、稀にしか起こらない問題なので断言が難しいのです。
0 件のコメント:
コメントを投稿