0

アプリにストアビューを入力して(アップルに製品を要求)、アップルからすべての製品がロードされる前にストアビューを閉じると、クラッシュすることに気付きました。

2012-11-05 12:32:08.420 Bellman[71368:c07] Dealloc inAppManager
2012-11-05 12:32:13.788 Bellman[71368:c07] *** -[InAppPurchaseManager respondsToSelector:]: message sent to deallocated instance 0x8e85a50

私のコードでわかるようにremoveTransactionObserver:、deallocが呼び出されたときに呼び出しています。上記のログでわかるように、アプリがクラッシュする5秒前にdeallocが呼び出されています。productsRequest: didReceiveResponse:オブザーバーとしての自分自身を削除したとしても、デフォルトのキューが呼び出そうとしていることを私は理解していますか?

- (void)requestProUpgradeProductData:(NSSet*)productIdentifiers
{
    self.productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:productIdentifiers];
    self.productsRequest.delegate = self;
    [self.productsRequest start];

}

- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{
    NSArray *products = response.products;
    NSLog(@"%@",products);

    for (NSString *invalidProductId in response.invalidProductIdentifiers)
    {
        NSLog(@"Invalid product id: %@" , invalidProductId);
    }

    [[NSNotificationCenter defaultCenter] postNotificationName:kInAppPurchaseManagerProductsFetchedNotification object:self userInfo:nil];
    [[self delegate] didLoadStore:response.products];
}

- (void)loadStore:(NSSet*)productIdentifiers
{
    // restarts any purchases if they were interrupted last time the app was open
    [[SKPaymentQueue defaultQueue] addTransactionObserver:self];

    // get the product description (defined in early sections)
    [self requestProUpgradeProductData:productIdentifiers];
    NSLog(@"Unfinished Transactions: [%i]", [[SKPaymentQueue defaultQueue].transactions count]);
}

- (BOOL)canMakePurchases
{
    return [SKPaymentQueue canMakePayments];
}

- (void)purchase:(SKProduct*)product {
    SKPayment *payment = [SKPayment paymentWithProduct:product];
    [[SKPaymentQueue defaultQueue] addPayment:payment];
}


- (void)recordTransaction:(SKPaymentTransaction *)transaction
{
    NSLog(@"Subscription bought");
}


- (void)provideContent:(SKPaymentTransaction *)transaction
{
    NSLog(@"Asking user to register Database");
    [[self delegate] provideContent:transaction];
}

- (void)finishTransaction:(SKPaymentTransaction *)transaction wasSuccessful:(BOOL)wasSuccessful
{
    // remove the transaction from the payment queue.
    [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
    NSLog(@"Removeing recipt");
    NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:transaction, @"transaction" , nil];
    if (wasSuccessful)
    {
        [[self delegate] didMakePurchase:transaction.payment.productIdentifier];
        // send out a notification that we’ve finished the transaction
        [[NSNotificationCenter defaultCenter] postNotificationName:kInAppPurchaseManagerTransactionSucceededNotification object:self userInfo:userInfo];
    }
    else
    {
        // send out a notification for the failed transaction
        [[NSNotificationCenter defaultCenter] postNotificationName:kInAppPurchaseManagerTransactionFailedNotification object:self userInfo:userInfo];
    }
}

- (void)completeTransaction:(SKPaymentTransaction *)transaction
{
    [self recordTransaction:transaction];
    [self provideContent:transaction];
}

- (void)restoreTransaction:(SKPaymentTransaction *)transaction
{

}

- (void)completePurches:(SKPaymentTransaction *)transaction {
    NSLog(@"EVERYTHING IS DONE!");
    [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"unfinishedReceipt"];
    [self finishTransaction:transaction wasSuccessful:YES];
}

- (void) failedTransaction: (SKPaymentTransaction *)transaction {
    if (transaction.error.code != SKErrorPaymentCancelled)
    {
        [[self delegate] didReciveAppStoreError:transaction.error.localizedDescription];
        // Optionally, display an error here.
    }
    [[self delegate] didCancelPurches];
    [[SKPaymentQueue defaultQueue] finishTransaction: transaction];
}


- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
{
    for (SKPaymentTransaction *transaction in transactions)
    {
        switch (transaction.transactionState)
        {
            case SKPaymentTransactionStatePurchased:
                NSLog(@"Completed transcation");
                [self completeTransaction:transaction];

                break;
            case SKPaymentTransactionStateFailed:
                NSLog(@"Failed transcation: %@",transaction.error);
                [self failedTransaction:transaction];
                break;
            case SKPaymentTransactionStateRestored:
                NSLog(@"Restore transcation: %@",transaction.payment.productIdentifier);
                [self restoreTransaction:transaction];
                break;
            case SKPaymentTransactionStatePurchasing:
                NSLog(@"ID: %@",transaction.transactionIdentifier);
                break;
            default:
                break;
        }
    }
}

-(void)didVerifyNewRecipt:(SKPaymentTransaction *)recipt wasNewRecipit:(BOOL)status {
    if (status) {
        NSLog(@"Was new recipt showing interface");
        [self completeTransaction:recipt];
    } else {
        NSLog(@"Was old Receipt");
        [self completePurches:recipt];
        [[self delegate] didFindOldReceipt];
    }
}

-(void)didReciveError:(NSString *)error {
    NSLog(@"ERROR! %@",error);
}

-(void)dealloc {
    [[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
    NSLog(@"Dealloc inAppManager");
}
4

1 に答える 1

2

私が「質問をする」を打つところだったとき、それはちょうどそれを理解しました。私はインターネットでこれに対する答えを見つけられなかったので、私は私の解決策を共有するつもりです。

はSKPaymentQueueSKProductsRequestの一部ではなく、SKProductsRequest独自のデリゲートを実装しているため、SKProductsRequestで設定したデリゲートを削除する必要があります。

-(void)dealloc {
   [[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
   self.productsRequest.delegate = nil; // <----- Solution
   NSLog(@"Dealloc inAppManager");
}
于 2012-11-05T11:58:39.963 に答える