我注意到如果你在我的应用程序中输入我的商店视图(向苹果询问产品),然后在从苹果加载所有产品之前关闭商店视图,它就会崩溃。
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
正如您在我的代码中看到的那样,当调用dealloc时,我正在调用removeTransactionObserver:
。正如您在上面的日志中所看到的,dealloc在应用程序崩溃前5秒被调用。根据我的理解,默认队列试图调用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");
}
答案 0 :(得分:2)
当我即将点击“提问”时,它只是想出来了。由于我没有在互联网上找到答案,我将分享我的解决方案。
由于SKProductsRequest
不是SKPaymentQueue的一部分而SKProductsRequest
实现了自己的委托,因此您需要删除您在SKProductsRequest上设置的委托。
-(void)dealloc {
[[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
self.productsRequest.delegate = nil; // <----- Solution
NSLog(@"Dealloc inAppManager");
}