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