Search code examples
ioscocos2d-iphonein-app-purchase

NSNotificationCenter sending deallocated message during app purchase


I know this question has been asked multiple times, but I am still having issues with it. I have some non-consumable app purchase code that works fine if the user stays in the scene and purchases them all at once. However, if the user leaves this menu and comes back to it, the code will crash while it is completing the transaction. I'm using cocos2d for what it's worth.

from MKStoremanager.m

-(void) provideContent: (NSString*) productIdentifier
{
    NSLog(@"productIdentifier=%@", productIdentifier);
     nc = [NSNotificationCenter defaultCenter];


        featureAPurchased = YES;
        [nc postNotificationName:@"featureAPurchased" object:nil]; //<--crashes here


    [MKStoreManager updatePurchases];
}

from MSStoreObverser.m

- (void) completeTransaction: (SKPaymentTransaction *)transaction {     NSLog(@"completeTransaction");
    NSLog(@"transaction.payment.productIdentifier=%@",transaction.payment.productIdentifier);

    //[[NSNotificationCenter defaultCenter] removeObserver:self];  //<--tried removing observer.  Still crashes

    [[SKPaymentQueue defaultQueue] finishTransaction: transaction];
    [[MKStoreManager sharedManager] provideContent: transaction.payment.productIdentifier];

}

- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
{
    NSLog(@"paymentQueue");

    for (SKPaymentTransaction *transaction in transactions)
    {
        switch (transaction.transactionState)
        {
            case SKPaymentTransactionStatePurchased:

                [self completeTransaction:transaction];  //<--Breaks here

                NSLog(@"Purchase was a success -J");
                break;

            case SKPaymentTransactionStateFailed:

                [self failedTransaction:transaction];

                break;

            case SKPaymentTransactionStateRestored:

                [self restoreTransaction:transaction];
                break;
            default:

                break;
        }           
    }
}

I think the issue is that the NSNotificationCenter observer isn't getting removed properly, but I'm not sure why.


Solution

  • As my comment suggested, we need to remove the observer as such to make sure we aren't sending messages to deallocated things.

    - (void)dealloc
    {
        [[NSNotificationCenter defaultCenter] removeObserver:self];
    }