2011-08-22 15 views
21

アプリ内購入のテストを実行しています(初めてアプリを購入したとき)。このコードの3行目にEXC_BAD_ACCESSが表示されます。アプリ購入テスト中のEXC_BAD_ACCESS

SKPayment *payment = [SKPayment paymentWithProduct:electronicProd]; 
    [[SKPaymentQueue defaultQueue] addTransactionObserver:self]; 
    [[SKPaymentQueue defaultQueue] addPayment:payment]; 

ボタンのIBActionの下にあります。 electronicPackはヘッダーにSKProductとして宣言されています。 productsRequest didReceiveResponseにいくつかのNSLogを投げました。そして、その製品が(viewDidLoadで)リクエストされたとき、彼らは製品を正しく取り出してそれをelectronicPackに格納していることを示しました。 didReceiveResponseページの[[request.products] objectAtIndex:0]として定義されたelectronicPack。そうです。それは私が何をすべきかわからないからです。どんな助けもありがとうございます。

UPDATE:FIXED誤ってコードに残って余分なトランザクションオブザーバを追加しました笑

+0

、あなたが保持してメッセージを呼ぶのですか?すべてのイベントは自動解放プールにラップされます。静的なinitメソッドでオブジェクトをインスタンス化すると、viewDidLoadメソッドが終了するとアイテムが解放されます。 – andreamazz

+0

私が好きかどうか尋ねていますか? electronicPack = [SKProduct alloc] init ?それに対する答えは「いいえ」です。もしあなたが何を求めていないのであれば、あなたは何を言っているのかよく分からない。笑 –

+0

私は全体のメモリ管理、プロパティのものであまりにも良いではありません。そしてすべて。約1ヶ月間しかプログラミングされておらず、まだそれを選んだことはありません。それを試してみて、何かを修正するかどうかを確認してください。 EDIT:何も変更せずにself.elec..etcを実装しました。まだアプリケーションがクラッシュしたときにエラー –

答えて

9

あなたがのviewDidLoadが自動解放プールにシステムによって包まれ

- (void)viewDidLoad { 
    //... stuff 
    SKProduct* electronicProduct = //... 
    [electronicProduct retain]; 
    //... otherstuff 
} 

を作成しているオブジェクトを保持する必要があります、paymentWithProduct:自動解放オブジェクトを返します。 viewDidLoadが完了すると、すべてのオートリリースオブジェクトが解放されます。そのため、後でアクセスしようとするとメモリアクセスが悪くなります。私は同じ問題を持っていた

39

、私の解決策は、私のアプリでは、アプリ内ストアを残すに

[[SKPaymentQueue defaultQueue] removeTransactionObserver:self]; 

を呼び出すことでした。 将来的に誰かを助けるでしょうか。

+1

あなたは私の一日を救った!ありがとう! –

+0

Ohhoo ..素晴らしい..ありがとう –

+0

私のために働いた、ありがとう! – JustMe

26

トランザクションオブザーバを削除する前にトランザクションオブザーバを追加しようとしているようです。この問題を解決するには、コントローラに次の項目を追加してください。

- (void)viewDidDisappear:(BOOL)animated 
{ 
    [super viewDidDisappear:animated]; 
    [[SKPaymentQueue defaultQueue] removeTransactionObserver:self]; 
} 

+1

これは私の答えでした。 Xcode 6.3とiOS 8.3で有効です – Paul

+2

優秀、ありがとう!!私にとっては、Mihael Isaev(下記)のコードを使ってViewDidDisappearに入れていました。 – Pieter

2

私は同じエラーがあったので、本当に簡単に解決できました。私のヘッダファイルでは、私はSKProductは宣言していた:

@property SKProduct *product; 

私はちょうどそれを変更:

@property (retain) SKProduct *product; 

とすべてが正常に動作します。 これは誰かを助けてくれることを願っています。

+0

私の問題を解決するようです。 – NSGodMode

11

Mr.Tの回答が最適です!私はここに、このremoveTransactionObserverを呼んで迅速に

deinit { 
    SKPaymentQueue.defaultQueue().removeTransactionObserver(self) 
} 
+0

あなたはどこにいますか? appdelegateファイル!? – Learn2Code

0

私は同じ問題を持って、私の解決策は [[SKPaymentQueue defaultQueue] removeTransactionObserver:自己]を呼び出すことでした。店舗オブザーバトランザクション終了/失敗/完了コールバック

1

あなたはそれが保持されなければならないことを忘れないでくださいSKPaymentTransactionObserverための専用のクラスを作成している場合に

私はこれを実現する前にエラーが発生しましたが、ここではAppDelegateに例を示します

electronicProd定義で
class AppDelegate: UIResponder, UIApplicationDelegate { 

    var window: UIWindow? 
    var myTransactionObserver: MyTransactionObserver! 


    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 

     // don't 
     let myTransactionObserver = MyTransactionObserver() 

     // do 
     myTransactionObserver = MyTransactionObserver() 

     SKPaymentQueue.default().add(myTransactionObserver) 

     return true 
    } 

    // ... 
} 
関連する問題