Sto lavorando su alcuni IAP using this tutorial.Completamento Handler causando EXC_BAD_ACCESS quando lo stesso metodo viene chiamato due volte
In primo luogo ho recuperare i prodotti con questo:
-(void)fetchAvailableProductsFirstLoad:(BOOL)firstTimeLoading {
[[IAPHelper sharedInstance] requestProductsWithCompletionHandler:^(BOOL success, NSArray *products) { ...
L'helper esegue la seguente:
- (void)requestProductsWithCompletionHandler:(RequestProductsCompletionHandler)completionHandler {
@synchronized(self) {
// 1
_completionHandler = [completionHandler copy];
// 2
_productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:_productIdentifiers];
_productsRequest.delegate = self;
[_productsRequest start];
}
}
Quando i prodotti sono restituiti o fallito il seguente viene chiamato:
#pragma mark - SKProductsRequestDelegate
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response {
NSLog(@"Loaded list of products...");
_productsRequest = nil;
NSArray * skProducts = response.products;
for (SKProduct * skProduct in skProducts) {
NSLog(@"Found product: %@ %@ %0.2f",
skProduct.productIdentifier,
skProduct.localizedTitle,
skProduct.price.floatValue);
}
_completionHandler(YES, skProducts);
_completionHandler = nil;
}
- (void)request:(SKRequest *)request didFailWithError:(NSError *)error {
NSLog(@"Failed to load list of products.");
NSLog(@"Error: %@",error);
_productsRequest = nil;
_completionHandler(NO, nil);
_completionHandler = nil;
}
Problema
0.123.Il problema che si verifica è quando l'utente avvia due volte il recupero o i prodotti. Ad esempio, i prodotti di recupero vengono richiamati su viewDidLoad, ma se l'utente ha una connessione brutto/lento e si allontana e torna al controller. Il recupero iniziale non viene annullato, quindi ne esistono due in esecuzione.
Credo che il problema è quando la seconda viene restituita e il puntatore è cambiato/non esiste/corrotto.
L'EXC_BAD_ACCESS errore di codice 2 si verifica sulla linea in questione:
_completionHandler(YES, skProducts);
O
_completionHandler(NO, nil);
Grazie, ho usato le parti di entrambe le risposte, ma questo era più vicino. Ho anche aggiunto un altro metodo '- (void) cancelProductRequest { [_productsRequest cancel]; _productsRequest = nil; } 'che annulla la richiesta corrente se si allontana da quel controller per salvare le richieste multiple. – StuartM
Great @StuartM, sicuramente meglio annullare la richiesta se non ne hai bisogno. Felice di poterti aiutare! – stefandouganhyde